我有角度摘要循环的可预测行为,但不知道如何以有效的方式解决它。所以,这里是: 我有一个指令,它使用几个选项创建bootstrap日期时间选择器。该指令具有一个隔离的作用域,其中包含对另一个作用域值的双向引用('= OuterScopeValue')。接下来是'compile'的'post'-part方法的代码:
post: function(scope, element) {
var opt = options;
opt.startDate = scope.startDate;
opt.endDate = scope.endDate;
opt.yearsSchedule = [];//scope.years;
$(element).datetimepicker(opt);
$(element).on('changeDate', function (ev) {
var fn = function() {
if (ev.date != null) {
if (scope.timing == null || scope.timing.valueOf() != ev.date.valueOf()) {
var value = (ev.date.valueOf()); // + (new Date().getTimezoneOffset() * 60000));
scope.timing = new Date(value).toGMTString();
}
} else {
if (scope.timing != null) {
scope.timing = null;
}
}
console.log(ev.date);
};
if (scope.$$phase || scope.$root.$$phase) {
fn();
} else {
scope.$apply(fn);
}
});
scope.$watch('disable', function(value) {
$(element).datetimepicker('reserveEnableOrDisableDates', value, true, false);
});
scope.$watch('reserve', function(value) {
$(element).datetimepicker('reserveEnableOrDisableDates', value, false, true);
});
scope.$watch('enable', function (value) {
$(element).datetimepicker('reserveEnableOrDisableDates', value, false, false);
});
scope.$watch('years', function(value) {
$(element).datetimepicker('updateYears', value);
});
scope.$watch('startDate', function(value) {
$(element).datetimepicker('setStartDate', value);
});
scope.$watch('endDate', function(value) {
$(element).datetimepicker('setEndDate', value);
});
scope.$watch('timing', function(value) {
if (value == null) {
$(element).datetimepicker('reset');
}
});
scope.$watch('interval', function(value) {
if (value != null) {
$(element).datetimepicker('updateInterval', value);
}
});
}
所以我们在这里得到的是一个changeDate
事件监听器(changeDate
总是由选择器触发)。此事件可以在两种情况下触发:服务器向我们发送了一些保留日期,这个日期是我们实际选择的日期,因此我们必须清除它或者我们点击选择器的“X”按钮来清除所选日期。在第一种情况下,来自服务器的数据通过广播事件传递给控制器(我正在使用SignalR及其侦听器,必须在集线器启动之前指定,我在提供程序的配置部分执行此操作,因此我无法访问我的控制器的范围,并且必须在模块的.config部分中通过$ rootScope服务广播我从服务器获得的数据:
var reserveFunction = function (msg) {
$rootScope.$broadcast('reserveEvent', msg);
};
然后我的控制器中有一个监听器,它在我的$scope.scopeReserve
值上调用$ apply来启动摘要循环并更新选择器值:
$scope.$apply(function() {
$scope.scopeReserve = [{ date: new Date(date.valueOf() + date.getTimezoneOffset() * 60000), reserved: false }];
});
顺便说一句,每次需要更新输入字段时,选择器都会启动另一个循环。目前的解决方案是使用这个反模式if (scope.$$phase || scope.$root.$$phase)
,问题是:我不需要调用$ apply,以防服务器向我发送一些数据(从控制器中的侦听器调用摘要循环)我需要当我通过按“x”按钮手动清除数据时启动循环。所以我想知道,我该如何修复它,甚至重新设计我的应用程序结构来解决这类问题。