Question

J'utilise ui-router dans un projet AngularJS où j'ai une vue imbriquée contenant une directive personnalisée.Cette directive restitue un champ de saisie (disons un champ de filtre) et sa valeur doit être synchronisée avec la portée du contrôleur.


Cela fonctionne bien pour cette directive, lorsque la vue/l'état n'est pas imbriqué :

jsFiddle / non imbriqué / fonctionne comme prévu

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);
    }
}]);

Voir:

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

Lorsque je modifie le texte du champ de saisie, cela se reflète dans la portée...


... mais lorsque j'imbrique la vue/l'état, la valeur sur la portée conserve sa valeur initiale mais je m'attends à ce qu'elle soit modifiée en fonction de la valeur du champ de saisie lors de l'écrasement.

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);
    }
}]);

Voir:

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

Ici, le texte sur le scope (voir contrôleur) reste le même.

Avez-vous une idée de la façon dont je peux obtenir le même résultat avec des vues imbriquées que dans le premier exemple ?

PS :La directive doit rester réutilisable

jsFiddle / imbriqué / ne fonctionne pas comme prévu

Était-ce utile?

La solution

Ceci est lié à un problème commun.Comme mentionné dans cette vidéo JS angulaire - meilleures pratiques (29:19), et expliqué ici : Portées imbriquées dans Angular JS

"Chaque fois que vous avez ng-model, il doit y avoir un point quelque part.Si vous n'avez pas de point, vous vous trompez."

Le contrôleur devrait donc créer un objet :

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);
    }    
}]);

et le modèle devrait fonctionner avec un objet ayant une propriété value:

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

La mise à jour jsfiddle

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top