2016-04-16 6 views
1

ich meine benutzerdefinierte Richtlinie eine UIB-Datepicker-Popup verkapseln erstellt:ng-Schalter in benutzerdefinierten Winkel Richtlinie bricht Zweiweg Bindung

'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; 
    } 
    } 
}; 

});

Der HTML-Teil ist dann:

<input-date ng-model="form.flight.date"></input-date> 

Das Problem: Wenn das Popup erscheint, wird scope.ngModel richtig aus attrs.ngModel initialisiert. Ich hatte ein Logbuch im Watcher, das mir zeigte, dass attrs.ngModel funktioniert, aber "ngModel" oder scope.ngModel zu sehen funktioniert nur, bis ich den Datepicker benutze. Es funktioniert einwandfrei, solange der Datepicker nicht ausgelöst wird. gerade entdeckt, dass es funktioniert perfekt, wenn ich der „ng-switch-default“ remvoe. Wenn Sie es durch ng-show/ng-hide ersetzen, funktioniert die Anweisung wie erwartet.

Kann jemand erklären warum?

Antwort

1

Das Verhalten, das Sie sehen, ist absolut richtig. Wenn Sie strukturelle Richtlinien wie ng-if verwenden, ng-switch, ng-repeat usw. schafft einen neuen Rahmen und kopiert alle Attribute des übergeordneten Bereich. Ihr Modell ist ein Primitiv (String), daher wird es vollständig in den neuen Bereich kopiert und in diesem Bereich ohne Weiterleitung an den übergeordneten Bereich geändert.

Was können Sie tun, ist:

  1. Verwenden Objekt anstelle Zeichenfolge die ng-model zu passieren, was persönlich hier finde ich sehr umständlich
  2. Verwenden ng-model von Controller-Objekt und nicht vom Anwendungsbereich

gehen auf dem zweiten Ansatz: Sie bereits bindToController verwenden und ein isolierter Umfang von scope: true, also nur statt Verfolgung das Modells mit Beobachtern binden sie an die Steuerung:

return { 
    bindToController: true, 
    scope: { 
    ngModel: '=' 
    }, 
    ... 

so ideal werden Sie nicht einmal Ihre Link-Funktion und in der Vorlage benötigen statt

'<div readonly name="readonlyText">{{ngModel | date : \'d.MMMM yyyy\'}}</div>' 

Verwendung

'<div readonly name="readonlyText">{{vm.ngModel | date : \'d.MMMM yyyy\'}}</div>' 

Warum ng-hide noch funktioniert? Es erstellt keinen neuen Bereich.

+1

Danke, Ansatz Nummer zwei funktioniert perfekt und geschrumpfte schön Funktion meines Link :) – choosyg

Verwandte Themen