AngularJS自定义指令双向绑定

Dav*_*vre 15 javascript angularjs angularjs-directive

如果我有一个没有模板的AngularJS指令,并且我希望它在当前作用域上设置属性,那么最好的方法是什么?

例如,一个计算按钮点击次数的指令:

<button twoway="counter">Click Me</button>
<p>Click Count: {{ counter }}</p>
Run Code Online (Sandbox Code Playgroud)

使用指令将点击计数分配给双向属性中的表达式:

.directive('twoway', [
'$parse',
  function($parse) {
    return {
      scope: false,
      link: function(scope, elem, attrs) {
        elem.on('click', function() {
          var current = scope.$eval(attrs.twoway) || 0;
          $parse(attrs.twoway).assign(scope, ++current);
          scope.$apply();
        });
      }
    };
  }
])
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?从我所读到的,一个孤立的范围将是矫枉过正,但我​​需要一个儿童范围?是否有更简洁的方法来回写指令属性中定义的范围变量而不是使用$parse.我觉得我让这个太难了.

Full Plunker 在这里.

Dou*_* T. 32

为什么隔离范围过大?它对于这种事情非常有用:

  scope: {
     "twoway": "=" // two way binding
  },
Run Code Online (Sandbox Code Playgroud)

对于这个问题,这是一个非常惯用的角度解决方案,所以这就是我坚持的.

  • 这个答案的关键补充是你传递给这个指令的变量,例如`counter`,**必须是一个对象,例如`obj.counter`,否则你将无法获得更新父对象的正确引用范围. (32认同)

jjp*_*aga 23

我很惊讶没有人提到过ng-model,这是做双数据绑定的默认指令.也许它不是那么出名,但链接功能有第四个参数:

angular.module('directive-binding', [])
  .directive('twoway', 
      function() {
        return {
          require: '?ngModel',
          link: function(scope, elem, attrs, ngModel) {
            elem.on('click', function() {
              var counter = ngModel.$viewValue ? ngModel.$viewValue : 0
              ngModel.$setViewValue(++counter);
              scope.$apply();
            });
          }
        };
      }
    );
Run Code Online (Sandbox Code Playgroud)

在你的观点

<button twoway ng-model="counter">Click Me</button>
<p>Click Count: {{ counter }}</p>
Run Code Online (Sandbox Code Playgroud)

第四个参数是ngModelController的API ,它具有许多用于处理(例如解析和格式化)以及在指令和范围之间共享数据的用途.

这是更新的Plunker.