简体   繁体   中英

Setting a two-way bound directive attribute in the HTML with AngularJS

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)
        });            ;
    }

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..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM