简体   繁体   中英

Angularjs custom directive two way binding not working

I create custom directive and using two way binding (=)

But I want to watch changes in controller when model is changed in directive.

<div ng-app="zippyModule">
  <div ng-controller="Ctrl3">
    Title: <input ng-model="title">
    <hr>
    <div class="zippy" zippy-title="title" ff="titleChanged()"></div>
  </div>
</div>


function Ctrl3($scope) {
  $scope.title = 'Lorem Ipsum';
    $scope.titleChanged = function() {
        //ALERT COMMING WITH OLD VALUE NOT UPDATED
         alert($scope.title);
    }
}

angular.module('zippyModule', [])
  .directive('zippy', function(){
    return {
      restrict: 'C',
      replace: true,
        scope: { title:'=zippyTitle',f:'&ff' },
      template: '<input type="text" value="{{title}}"style="width: 90%" ng-click="onclick()"/>',
      link: function(scope, element, attrs) {
        // Your controller
          scope.onclick = function() {
               scope.title +="_";
              if (scope.$root.$$phase != '$apply' && scope.$root.$$phase != '$digest') {
                    scope.$apply();
              }
              scope.f();

          }
      }
    }
  });

titleChanged method is calling but $scope.title is comming with old value. if I remove

if (scope.$root.$$phase != '$apply' && scope.$root.$$phase != '$digest') {

this if and call direcly scope.$apply() method,

Apply in progress exception is throwing.

As @Omri said above, you should put your model values inside an object on your scope instead of having strings directly on the scope.

However, you probably want to just use ng-model to handle tracking model changes:

  angular.module('zippyModule', [])
      .controller('Ctrl3', function($scope) {
      $scope.model = {title : 'Lorem Ipsum'};
        $scope.titleChanged = function() {
            //ALERT COMMING WITH OLD VALUE NOT UPDATED
             alert($scope.model.title);
        }
      })
      .directive('zippy', function(){
        return {
          restrict: 'C',
          replace: true,
            scope: {f:'&ff' },
            require: 'ngModel',
          template: '<input type="text" style="width: 90%" ng-click="onclick()"/>',
          link: function(scope, element, attrs, ctrl) {
            // Use ngModelController
              ctrl.$render = function() {
                element.val(ctrl.$modelValue);
              };
              scope.onclick = function() {
                var newVal = ctrl.$modelValue + '_';
                element.val(newVal);
                ctrl.$setViewValue(newVal);
                scope.f();
              }
          }
        }
      });

Then update your HTML to use ng-model:

    <div ng-app="zippyModule">
      <div ng-controller="Ctrl3">
        Title: <input ng-model="model.title">
        <hr>
        <div class="zippy" zippy-title ng-model="model.title" ff="titleChanged()">
        </div>
      </div>
    </div>

Fiddle: https://jsfiddle.net/sLx9do3c/

Check out the docs for ngModelController for all the other features that you probably will eventually need. https://docs.angularjs.org/api/ng/type/ngModel.NgModelController

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