AngularJS指令中的属性更改通知 [英] Property change notification in AngularJS Directive

查看:62
本文介绍了AngularJS指令中的属性更改通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个页面,其中包含大量类似Excel布局的文本框.每列代表一个对象,该列中的单元格包含该对象的属性.当单元格中的值发生更改时(单元格失去焦点时触发),我需要知道发生更改的对象和属性,以便可以将值复制到其他选定对象中的同一属性.

I have a page with a large number of text boxes in an Excel-like layout. Each column represents a single object, and the cells in that column contain the object's properties. When a value in a cell changes (triggered when cell loses focus), I need to know the object and property that changed so that I can copy the values to the same property in other selected objects.

我有这个工作,但是这是一种幼稚的方法,我认为将其封装在指令中会更好.问题在于我能够编写的指令像我的第一个解决方案一样冗长,似乎并没有改善.

I have this working but it's a naive approach and I think it would be better to encapsulate this in a directive. The problem is that the directive I was able to write is as verbose as my first solution and doesn't seem to be an improvement.

第一版只是将对象和属性名称传递给更改处理程序函数.

The first version simply passes the object and property name to a change handler function.

<td>
    <input ng-model="person.firstName" 
           ng-change="personChanged(person, 'firstName')" 
           ng-model-options="{updateOn: 'blur'}" />
</td>

$scope.personChanged = function(person, property) {
  alert(person.personId + ' : ' + property);
}

第二版使用了指令.

<td>
    <input ng-model="person.firstName" 
           name-changed person="person" property="'firstName'" />
</td>

myApp.directive('nameChanged', function() {
  return {
    restrict: 'A',
    scope: {
      person: '=',
      property: '='
    },
    link: function(scope, element, attrs){
      element.bind('change', function(e){
        alert(scope.person.personId + ' : ' + scope.property);
      });
    }
  };
});

在两种解决方案中,我都在属性中声明对象和属性名称,这似乎是多余的,因为我已经通过ngModel提供了两者.什么是正确的方法?

In both solutions, I am declaring the object and property name in attributes, which seems redundant because I have already provided both via ngModel. What is the right way to do this?

推荐答案

编写 ngModel ="person.firstname" 时,angular将侦听firstname属性的任何更改,并且仅保留该值ngModel中的名字(查看ngModel和ngModelController上的文档).这意味着您必须在指令范围内传递其他信息(例如person.id,property)

When you write ngModel="person.firstname", angular will listen any changes on firstname attribute and it will only keep the value of firstname in you ngModel (check documentation on ngModel and ngModelController). That means you have to pass other information in your directive scope (eg person.id, property)

您应尽可能避免双向绑定.使用&"当您将属性绑定到指令范围时,则为'@'.

You should avoid two way binding where you can. Use '&' and '@' when you bind attributes to your directive scope.

指令的优化版本:

myApp.directive('nameChanged', function() {
  return {
    require: 'ngModel',
    restrict: 'A',
    scope: {
      person: '&',
      property: '@'
    },
    link: function(scope, element, attrs, ngModel){
      element.bind('change', function(e){

        alert(scope.person().personId  + ' : ' + scope.property + ', value is : ' + ngModel.$modelValue)

      // dispatch your change to upper scopes
      scope.$emit('nameChanged', {personId : scope.person().personId, property: scope.property, value : ngModel.$modelValue});

      });
    }
  };
});

然后在您的控制器中处理此事件:

then in your controller handle this event :

myApp.controller('peopleController', function($scope) {
  $scope.people = [new Person(1, 'Homer', 'Simpson'), new Person(2, 'Ned', 'Flanders'), new Person(3, 'Otto', 'Mann')];


  $scope.$on('nameChanged', function(event, change){
    // changed detected inside one of ours dirctives
    console.log('changed detected from controller', change)     
    // do what you want with he new value : 'change.value'

  })

});

请注意,事件名称应位于.constant模块中.更好的可维护性.

Note that event names should be in .constant module. It is better for maintainability.

在此处插入

您可以通过两种方式(在您的作用域中使用ng-change和fn)或使用单独的作用域指令来实现所需的功能.我个人喜欢在指令中这样做以隔离责任,但这取决于您.

You can achieve what you want both ways (with ng-change and an fn in your scope) or with a isolate scope directive. Personally I like doing it in directives to isolate responsability but it depends on you.

这篇关于AngularJS指令中的属性更改通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆