我创建了自定义指令来封装uib-datepicker-popup:
'use strict';
angular.module( 'frontendApp' )
.directive( 'inputDate', function(){
var controller = function(){
var vm = this;
function init() {
vm.formats = [ 'dd.MMMM yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate' ];
vm.format = vm.formats[ 0 ];
vm.altInputFormats = [ 'M!/d!/yyyy' ];
vm.dateOptions = {
datepickerMode: 'day',
formatYear: 'yy',
maxDate: new Date(),
minDate: new Date( 1900, 1, 1 ),
startingDay: 1
};
vm.datepicker = {
opened: false
};
};
init();
vm.showDatePicker = function(){
vm.datepicker.opened = true;
};
};
var template = '<div ng-switch on="readonly" >' +
'<div ng-switch-when="true" class="form-control" readonly>' +
'<div readonly name="readonlyText">{{ngModel | date : \'d.MMMM yyyy\'}}</div>' +
'</div>' +
'<div ng-switch-default class="input-group">' +
'<input class="form-control" type="text" uib-datepicker-popup="{{vm.format}}" ng-model="ngModel" ng-model-options="{timezone:\'UTC\'}" is-open="vm.datepicker.opened" datepicker-options="vm.dateOptions" ng-required="true" show-button-bar="false" alt-input-formats="vm.altInputFormats" />' +
'<span class="input-group-btn">' +
'<button type="button" class="btn btn-default" ng-click="vm.showDatePicker()"><i class="glyphicon glyphicon-calendar"></i></button>' +
'</span>' +
'</div>' +
'</div>';
return{
controller: controller,
controllerAs: 'vm',
bindToController: true,
template: template,
restrict: 'EA',
scope :true,
require:'ngModel',
link: function( scope, element, attrs, ngModel ){
// Bring in changes from outside:
scope.$watch( 'ngModel', function(){
if( ngModel ) {
scope.$eval( attrs.ngModel + ' = ngModel' );
}
} );
// Send out changes from inside:
scope.$watch( attrs.ngModel, function( val ){
if( val ) {
scope.ngModel = val;
}
} );
if( attrs.readonly === 'true' ) {
scope.readonly = true;
}
}
};
});
html部分是:
<input-date ng-model="form.flight.date"></input-date>
问题:如果弹出窗口显示,则从attrs.ngModel正确初始化scope.ngModel。我在守望者里面写了一个日志,告诉我看着attrs.ngModel完美地工作,但是看着&#39; ngModel&#39;或scope.ngModel仅在我使用datepicker之前有效。只要未触发日期选择器,它就能完美运行。 刚刚发现,如果我重新启动它,它的效果非常好 &#34; NG-开关默认&#34 ;.用ng-show / ng-hide替换它使指令完全按预期工作。
任何人都可以解释原因吗?
答案 0 :(得分:1)
您看到的行为绝对正确。当您使用ng-if
,ng-switch
,ng-repeat
等结构指令时,它会创建新范围并复制父范围的所有属性。您的模型是基元(字符串),因此它完全复制到新范围并在此范围内更改而不传播到父范围。
你能做的是:
ng-model
,我个人觉得这里很尴尬ng-model
而不是来自范围继续使用第二种方法:您已经使用bindToController
和scope: true
的隔离范围,因此只需使用观察者跟踪模型,将其绑定到控制器:
return {
bindToController: true,
scope: {
ngModel: '='
},
...
理想情况下,您甚至不需要链接功能,而是在模板中而不是
'<div readonly name="readonlyText">{{ngModel | date : \'d.MMMM yyyy\'}}</div>'
使用
'<div readonly name="readonlyText">{{vm.ngModel | date : \'d.MMMM yyyy\'}}</div>'
为什么ng-hide
仍有效?它不会创建新的范围。