【问题标题】:Trigger $scope.$watch on angular component在角度分量上触发 $scope.$watch
【发布时间】:2016-11-28 19:41:21
【问题描述】:

我有这个可以正常工作的组件。 它进行 utc->local 和 local->utc 转换(应用逻辑需要)。

在模型中,日期始终为UTC,但为了显示,日期需要以当地时间显示,当在UI中更改时,模型将具有UTC转换的日期。

$scope.$watch 按预期工作 - 当用户尝试更改日期时。

唯一的问题是 - 如果用户决定不更改日期,这个 $scope.$watch 将不会被触发,并且不会有任何转换。

在这种情况下我该怎么办?

Angular/TypeScript 组件:

class RsDateTimeController {
    value: Date;
    displayValue: Date;

    static $inject = ["$scope"];

    constructor($scope: ng.IScope) {
        $scope.$watch(
            "$ctrl.displayValue",
            (newValue: Date, oldValue: Date) => {
                if (newValue != oldValue) {
                    this.value = Utility.toUtcDate(newValue);
                }
            }
        );
    }

    $onInit() {
        if (this.value) {
            this.displayValue = Utility.toLocalDate(this.value);
        }
    }

}

class RsDateTimeComponent implements ng.IComponentOptions {
    public bindings: any;
    public controller: any;
    public template: string;

    constructor() {
        this.template = "<input type='datetime-local' class='form-control' ng-model='$ctrl.displayValue'>";
        this.bindings = {
            value: "="
        };
        this.controller = RsDateTimeController;
    }
}

HTML:

app.component("rsDatetime", new RsDateTimeComponent());

    <div class="form-group">
        <label>@("Status Date".T())</label>
        <rs-datetime ng-if="vm.woChangeStatus" value="vm.woChangeStatus.StatusDate"></rs-datetime>
    </div>

【问题讨论】:

  • 您使用的是 Angular 2.0 吗?我问是因为在 2.0 中 $watch 不再需要。
  • 你为什么不把 this.value 初始化为一些默认值呢?因此,如果用户不更改日期,它将显示默认值。
  • 弗里希,角 1.5.хх
  • Hoyen,我愿意,初始化它,但正如我所说,模型中的所有日期值都是 UTC 格式,在 $onInit 中它们将转换为本地时间以进行显示。但是,如果用户不更改该组件中的日期,则不会触发 $scope.$watch,并且本地时间显示的日期将作为本地时间发送到模型,$scope.$watch 内部的转换不会发生。

标签: angularjs typescript


【解决方案1】:

这正是$watch 的功能,它将触发您指定的侦听器回调。当用户不进行任何更改时,模型不脏,因此$watch 不会触发。

这里有两件事在起作用:当模型改变时,视图应该更新,当视图改变时,底层模型应该更新。

更新答案

基于 cmets 中的对话,我将编写一个过滤器,它只进行转换(UTC -> 本地显示值)并在 UI 中使用它。

这是一种更简洁的方法,如果用户不进行任何更改,它不会要求您跳过转换显示值的麻烦。那么,只有当用户发起更改时,您的组件才会转换,而这已经发生了。

【讨论】:

  • 不确定我是否理解。您会看到以下代码: this.value = Utility.toUtcDate(newValue);仅当用户更改 rs-datetime 组件中的任何内容时,它才会执行。如果他没有呢?我仍然需要执行这段代码。
  • 我现在意识到,我已经在更新中发布了想法。如果没有用户触发事件,就无法真正知道 何时 进行转换。我假设您将这个模型保存在某个地方,这可能是您可以执行转换的地方。
  • 我已经完成了所有的转换。我问的是组件。正如我已经提到的,在我的模型中,所有日期都是 UTC 格式。组件进行转换:utc->local 用于显示,local->utc 用于 UI 中的值更改。该组件就是这样做的。又是一个问题:如何让组件在 $scope.$watch 内运行,但无需用户更改值。也许有一种方法可以在没有用户干预的情况下模拟日期时间变化?
  • 好的。在这种情况下,我会编写一个过滤器来简单地进行转换(UTC -> 本地显示值)并在 UI 中使用它。这是一种更简洁的方法,如果用户不进行任何更改,它不会要求您跳过转换显示值的过程。那么,只有当用户发起更改时,您的组件才会转换,而这已经发生了。
  • 我有一个只读视图过滤器。如您所见,此组件用于表单中,用户必须输入日期/时间。
猜你喜欢
  • 2016-03-07
  • 2016-06-19
  • 1970-01-01
  • 1970-01-01
  • 2014-03-24
  • 2013-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多