Direktiven isolierter Bereich funktioniert nicht richtig zusammen mit verschachtelten Ansichten?(AngularJS / Benutzeroberflächenrouter)

StackOverflow https://stackoverflow.com//questions/23043216

Frage

Ich verwende ui-router in einem AngularJS-Projekt, in dem ich eine verschachtelte Ansicht habe, die eine benutzerdefinierte Direktive enthält.Diese Direktive rendert ein Eingabefeld (sagen wir ein Filterfeld) und sein Wert sollte mit dem Gültigkeitsbereich des Controllers synchronisiert sein.


Dies funktioniert gut für diese Direktive, wenn die Ansicht / der Status nicht verschachtelt ist:

jsFiddle / nicht verschachtelt / funktioniert wie erwartet

var myApp = angular.module('myApp', ['ui.router', 'myComponents'])
    .config(['$stateProvider', function ($stateProvider) {
        $stateProvider.
            state('home', {
                url: '',
                template: '<my-filter text-filter="theFilter"></my-filter><button ng-click="inspect()">inspect</button>{{ theFilter |json}}',
                controller: 'myController'
            });
    }]);

var components = angular.module('myComponents', []);

components.directive('myFilter', [function () {
    return {
        restrict: 'E',
        template: '<input type="text" name="filter" ng-model="textFilter">',
        scope: {
            textFilter: '='
        }
    };
}]);

components.controller('myController', ['$scope', function ($scope) {
    $scope.theFilter = 'initial filter';

    $scope.inspect = function () {
        alert($scope.theFilter);
    }
}]);

Blick:

<div ng-app="myApp">
    <div ui-View></div>
</div>

Wenn ich den Text des Eingabefelds ändere, wird er im Bereich angezeigt...


...aber wenn ich die Ansicht / den Status verschachtele, behält der Wert im Bereich seinen Anfangswert bei, aber ich erwarte, dass er beim Überschreiben entsprechend dem Wert des Eingabefelds geändert wird.

var myApp = angular.module('myApp', ['ui.router', 'myComponents'])
    .config(['$stateProvider', function ($stateProvider) {
        $stateProvider.
            state('home', {
                abstract: true,
                url: '',
                template: 'Nested View:<div ui-view></div>',
                controller: 'myController'
            }).
            state('home.detail', {
                url: '',
                template: '<my-filter text-filter="theFilter"></my-filter><button ng-click="inspect()">inspect</button>{{ theFilter |json}}'
            });;
    }]);


var components = angular.module('myComponents', []);

components.directive('myFilter', [function () {
    return {
        restrict: 'E',
        template: '<input type="text" name="filter" ng-model="textFilter">',
        scope: {
            textFilter: '='
        }
    };
}]);

components.controller('myController', ['$scope', function ($scope) {
    $scope.theFilter = 'initial filter';

    $scope.inspect = function () {
        alert($scope.theFilter);
    }
}]);

Blick:

<div ng-app="myApp" >
    <div ui-View></div>
</div>

Hier bleibt der Text auf dem Umfang (siehe Controller) gleich.

Irgendeine Idee, wie ich mit verschachtelten Ansichten das gleiche Ergebnis erzielen kann wie im ersten Beispiel?

PS:Die Richtlinie muss wiederverwendbar bleiben

jsFiddle / verschachtelt / funktioniert nicht wie erwartet

War es hilfreich?

Lösung

Dies hängt mit einem häufigen Problem zusammen.Wie in diesem Video erwähnt angular JS - bewährte Methode (29:19), und hier erklärt: Verschachtelte Bereiche in Angular JS

"Wann immer du ein ng-Modell hast, muss irgendwo ein Punkt drin sein.Wenn Sie keinen Punkt haben, machen Sie es falsch."

Der Controller sollte also ein Objekt erstellen:

components.controller('myController', ['$scope', function($scope) {

    // here theFilter is an object
    // with property value
    $scope.theFilter =  { value : 'initial filter'};

    $scope.inspect = function() {
        alert($scope.theFilter.value);
    }    
}]);

und die Vorlage sollte mit einem Objekt mit Eigenschaft funktionieren value:

components.directive('myFilter', [function() {
    return {
        restrict: 'E',
        template: '<input type="text" name="filter" ng-model="textFilter.value">',
        scope: {
            textFilter: '='             
        }
    };          
}]);

Das aktualisierte jsfiddle

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top