【问题标题】:Angular 1.5 component track object changesAngular 1.5 组件跟踪对象更改
【发布时间】:2016-12-22 07:17:34
【问题描述】:

我有一个 Angular 1.5(带组件)应用程序。在其中一个组件中,我有一个本地对象定义为:

model.user = {
  firstName: 'John',
  lastName: 'Smith'
}

然后在标记中我将其用作:

<input class="field" ng-model="model.user.firstName" />

我想做的是跟踪用户何时更改此字段并记录事件。我花了一些时间研究不同的选项,但我想问一下在使用组件时建议的方法是什么。这是我目前发现的:

  • $watch(...) - 这很有效,因为我得到了旧值和新值,但似乎不鼓励这种方法。
  • $onChanges - 这不起作用,因为这是一个本地对象。
  • $doCheck - 这可能会起作用,但我没有得到有关更改对象的任何信息。我必须手动跟踪以前的值。
  • ng-change - 这行得通,但我有很多字段,维护标记可能会有点困难。

我正在寻找像 Telerik 的 kendo MVVM 这样的方法。在那里,我可以将任何对象的更改事件绑定到一个函数,并检索已更改的字段、旧值和新值。这种方法的美妙之处在于,如果我的对象发生更改,我不必对我的代码进行任何更改,更改事件将获取新字段,而无需我编写任何代码。更清洁,更易于维护。

在 angular 1.5 中是否可以使用组件?如果是,推荐的方法是什么?

谢谢。

【问题讨论】:

  • ng-change 不再需要$watches,因此它在性能方面会发挥最佳效果。我不确定您通过维护标记指的是什么问题,因为如果您不这样做,那么这只是花更多时间维护控制器中的 javascript 的权衡。还是我错过了您的具体问题?
  • 感谢@CShark。我指的是这样一个事实,例如,在使用 kendo observables 时,一旦我在对象的“更改”事件处理程序中编写代码,如果我向该对象添加或删除字段,我就不需要触摸它。我也不必在标记中引用它。如果我使用 ng-change,我必须确保我需要跟踪的每个字段在标记中都有正确的代码。随着解决方案的增长,这可能会变得更加难以管理。你可以猜到,我是从大量使用 kendo ui 开始的 :) 我希望 Angular 有一个类似的机制我可以使用。

标签: angularjs angular-components


【解决方案1】:

正如@CShark 建议的那样,ng-change 方法是最好的选择。为了让它在标记中不那么冗长,我创建了一个自定义属性指令,该指令注入 ng-model-options 和 ng-change 属性:

module.directive('inputChanged', function ($compile) {
        function link(scope, element, attrs) {
            var field = attrs.ngModel;
            if (field) {
                element.removeAttr('input-changed');
                element.attr('ng-model-options', "{ updateOn: 'blur' }");
                var fn = "model.changed('" + field + "', " + field + ", '{{ " + field + " }}')";
                element.attr('ng-change', fn);

                $compile(element)(scope);
            }    
        }

        return {
            restrict: 'A',
            link: link,
            terminal: true,
            priority: 1000
        }
    });

在我的模型中,我有:

model.changed = function (field, newValue, oldValue) {
  //log the change
}

完成后,只需将 input-changed 属性添加到任何具有 ng-model 属性的元素。例如

&lt;input ng-model="model.user.firstName.value" input-changed /&gt;

请注意,我仅在用户通过设置 ng-model-options 提交更改后才捕获更改。另请注意,我将旧值和新值都传递给了 model.changed 函数。这样我就可以在不实际使用 $watch 的情况下实现类似于 $watch 的功能。

我不确定这是否是最好的解决方案,但在我的场景中可以。

【讨论】:

    猜你喜欢
    • 2012-01-02
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    相关资源
    最近更新 更多