1

I can not get the two ways data binding working in AngularJS directive.

Here is my html code from the template, used with a basic controller instantiating mymodel (an array here) :

HTML

<select ng-if="mymodel" multipleselect values="mymodel">

DIRECTIVE

I have a directive called multipleselect :

return {
  restrict: 'A',
  scope : {
    values : '='
  },
  link : function($scope, element, attrs){

    ...
    $scope.values = ["some","nice","datas"]; //Actually works, the model is changed in the controller 

    $("select").change(function(){ //This is a callback, asynchronous situation
        $scope.$apply(function () { //Using apply to notify the controller that we are changing its model
          $scope.values = ["some","amazing","datas"]; //Not working :(
        });
    });
   }
}

Why my model is not updated the second time I change it ?

2
  • Where did you define your mymodel property ? As you're using 2-way binding in your directive, there should be mymodel property defined on the scope of the enclosing/parent element of your multipleselect directive. Commented Jan 20, 2016 at 13:19
  • Ive had issues in the past with ng-if and such things like this, it will remove the actual element from the DOM and replace it. Don't know if it could be a similar issue. Also just so you know your change will fire for every select on the page. You should use the element object to scope your event to the directive. You should also listen to the destroy to event to remove the handler when it is remove in the ng-if. Could cause memory leaks. Commented Jan 20, 2016 at 13:24

2 Answers 2

2

Looking at the answers given I think this will fit your needs without having to use a custom directive:

<select ng-if="mymodel" multiple ng-model="model.mymodel">

Your model will automatically update when the select changes as can be seen here.

The egghead.io video "The Dot" has a really good overview, as does this very popular stack overflow question: What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

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

4 Comments

@ste2425 You should always use a . notation when using ng-model, see this fiddle: jsfiddle.net/vewk68xt/2
EDIT: Sorry, yea my bad was being daft,
@ste2425 Check my response
Thank you very much it works ! I will look at the sources because for now I really don't understand why it is working
0

You don't need to use jQuery to watch for the change. You can write like this (also to fix your problem):

return {
  restrict: 'A',
  scope : {
    values : '='
  },
  link : function($scope, element, attrs){

    $scope.values = ["some","nice","datas"];

    element.on("change", function(){
         $scope.values = ["some","amazing","datas"];
    });
   }
}

8 Comments

Element is a jQuery ( or jQLite if jQuery is not included before angular) object of the directive.
Why not use ng-change ?
@MartijnWelker because the directive does not specify a template. You would have to manually compile the html to add the bindings for ng-change.
@ShashankAgrawal which to me looks like it is because he doesn't fully understand Angular, therefore I've added an Angular example.
@ValentinV Here's the angular version for Select2, use this instead: github.com/angular-ui/ui-select
|

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.