Angularjs 触发$scope.$watch在角度组件上

Angularjs 触发$scope.$watch在角度组件上,angularjs,typescript,Angularjs,Typescript,我有一个工作正常的组件。 它执行utc->local和local->utc转换(应用程序逻辑需要) 在模型中,日期始终以utc为单位,但为了显示,日期需要以本地时间显示,当在UI中更改时,模型将使用utc转换日期 $scope.$watch按预期工作-当用户尝试更改日期时 唯一的问题是-如果用户决定不更改日期,则不会触发此$scope.$watch,也不会进行任何转换 在这种情况下我能做什么 角度/类型脚本组件: class RsDateTimeController { value: D

我有一个工作正常的组件。 它执行utc->local和local->utc转换(应用程序逻辑需要)

在模型中,日期始终以utc为单位,但为了显示,日期需要以本地时间显示,当在UI中更改时,模型将使用utc转换日期

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

唯一的问题是-如果用户决定不更改日期,则不会触发此$scope.$watch,也不会进行任何转换

在这种情况下我能做什么

角度/类型脚本组件:

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;
    }
}
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>
类RsDateTimeController{
值:日期;
显示值:日期;
静态$inject=[“$scope”];
构造函数($scope:ng.IScope){
$scope.$watch(
“$ctrl.displayValue”,
(新值:日期,旧值:日期)=>{
如果(新值!=旧值){
this.value=Utility.toUtcDate(newValue);
}
}
);
}
$onInit(){
if(该值){
this.displayValue=Utility.toLocalDate(this.value);
}
}
}
类RsDateTimeComponent实现ng.IComponentOptions{
公共约束:任何;
公共控制人:任何;
公共模板:字符串;
构造函数(){
此为.template=“”;
此文件的绑定={
值:“=”
};
this.controller=RsDateTimeController;
}
}
HTML:

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;
    }
}
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>
app.component(“rsDatetime”,新的RsDateTimeComponent());
@(“状态日期”.T())

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

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

最新答案

根据评论中的对话,我将编写一个过滤器,它只进行转换(UTC->local display value),并在UI中使用它


这是一种更简洁的方法,如果用户不做任何更改,也不会要求您跳过转换显示值的过程。那么,您的组件只有在用户发起更改时才会转换,它已经这样做了。

您使用的是Angular 2.0吗?我这样问是因为在2.0
中不再需要$watch
。为什么不将此.value初始化为某个默认值?因此,如果用户不更改日期,它将显示default.frishi,angular 1.5.crmk_Hoyen,我会初始化它,但正如我所说的,模型中的所有日期值都是UTC格式,单位为$onInit,它们将转换为本地时间显示。但是,如果用户不更改该组件中的日期,$scope.$watch将不会启动,并且在本地时间中显示的日期将作为本地时间发送到模型,则$scope.$watch中的转换不会发生。我不确定是否理解。您可以看到以下代码:this.value=Utility.toUtcDate(newValue);仅当用户更改rs datetime组件中的任何内容时,它才会执行。如果他没有呢?我仍然需要执行这段代码。我意识到现在,我已经在更新中发布了想法。如果用户不触发事件,就无法真正知道何时进行转换。我假设你将这个模型保存在某个地方,在那里你可以执行转换。我已经准备好了所有的转换。我在问有关组件的问题。在我的模型中,我已经提到的所有日期都是UTC格式的。组件进行转换:utc->local用于显示,而local->utc用于在UI中更改值。组件就是这样做的。问题又来了:如何让组件运行$scope.$watch中的内容,但不需要用户更改值。也许有一种方法可以在没有用户干预的情况下模拟日期-时间的变化?好的。在这种情况下,我会编写一个过滤器,只进行转换(UTC->local display value),并在UI中使用它。这是一种更简洁的方法,如果用户不做任何更改,也不会要求您跳过转换显示值的过程。那么,您的组件只有在用户发起更改时才会转换,它已经这样做了。我有一个只读视图的过滤器。如您所见,该组件用于表单中,用户必须在表单中输入日期/时间。