O escopo isolado das diretivas não funciona corretamente em conjunto com visualizações aninhadas?(Roteador AngularJS/UI)

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

Pergunta

Estou usando o ui-router em um projeto AngularJS onde tenho uma visualização aninhada que contém uma diretiva personalizada.Esta diretiva renderiza um campo de entrada (digamos um campo de filtro) e seu valor deve estar sincronizado com o escopo do controlador.


Isso funciona bem para esta diretiva, quando a visualização/estado não está aninhada:

jsFiddle/não aninhado/funcionando conforme esperado

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

Visualizar:

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

Quando altero o texto do campo de entrada, ele se reflete no escopo...


... mas quando aninho a visualização/estado, o valor no escopo mantém seu valor inicial, mas espero que seja alterado de acordo com o valor do campo de entrada ao substituir.

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

Visualizar:

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

Aqui, o texto no escopo (ver controlador) permanece o mesmo.

Alguma ideia de como posso obter o mesmo resultado com visualizações aninhadas do primeiro exemplo?

PS:A diretiva precisa de permanecer reutilizável

jsFiddle/aninhado/não funciona como esperado

Foi útil?

Solução

Isso está relacionado a um problema comum.Como mencionado neste vídeo Angular JS - melhores práticas (29:19), e explicado aqui: Escopos aninhados em Angular JS

“Sempre que você tem um modelo ng, deve haver um ponto em algum lugar.Se você não tem um ponto, você está fazendo errado."

Portanto, o controlador deve criar um objeto:

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

e o modelo deve funcionar com um objeto com propriedade value:

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

O atualizado jsfiddle

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top