0

I'm just starting out with AngularJs and have run into an issue that might be the result of not understanding directives / controllers /isolated scope properly. I'm trying to find a way to set a directive attribute to true/false from the html, and keep a property on the controller consistent with that attribute. What I'm working with is:

  1. A controller (LoginController) with the property signUpEnabled
  2. A directive (myLogin) that returns this:

        var directive = {
        bindToController: true,
        controller: 'LoginController',
        controllerAs: 'loginVm',
        templateUrl: 'login/my-login.directive.html',
        restrict: 'E',
        scope: {
            signUpEnabled: '='
        }
    };
    
  3. HTML where the directive is used like so:

    <my-login sign-up-enabled="true">

I get the error: Error: [$compile:nonassign] Expression 'true' used with directive 'frintLogin' is non-assignable!

It works ok when I set signUpEnabled to false in the HTML - possibly because that's what the property is initialised to in the controller. Am I going about this wrong, or have I missed something (like watching signUpEnabled in the directive's link function?)

[edit] Thanks for your help. Not sure if this is a good way to do things but I think I can get the behaviour I want by adding this link function to the directive (after changing the binding of signUpEnabled on the isolate scope to '@'):

    function link(scope, element, attrs, ctrl) {
        $timeout(function() {
            ctrl.signUpEnabled = scope.$eval(attrs.signUpEnabled)
        });            ;
    }
1
  • 1
    The way that you have that written, the it is looking for a property called "true" on the scope that exists outside your directive. See the section on "scope" in the docs: docs.angularjs.org/api/ng/service/… Commented Dec 1, 2015 at 21:10

1 Answer 1

1

A two way binding implies that you can do scope.signUpEnabled = something as well as something = scope.signUpEnabled. Since you're setting sign-up-enabled="true" in the directive, you're getting that error because you can't possibly set "true" to anything.

It sounds like you need a @ binding instead. That'll let you set the sign-up-enabled attribute to a string.

EDIT: Oops, just realized you're trying to keep the value consistent with a controller variable. In that case, keep the binding as = but set sign-up-enabled=scopeFieldFromController instead. You'll also want to initialize $scope.scopeFieldFromController=true in the controller.

Hope that wasn't too confusing..

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! So is it not possible to set that value from the HTML? The controller controls multiple views, with the only difference between them being based on whether that property (signUpEnabled) is true or not.
Nope, not with a 2-way binding -- it'll have to be defined in the controller. If signUpEnabled is always true in that specific view, then perhaps you need the @ binding.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.