Domanda

Sto usando l'ui-router in un progetto AngularJS in cui ho una vista annidata che contiene una direttiva personalizzata. Questa direttiva rende un campo di input (consente di dire un campo filtro) e il suo valore dovrebbe essere sincronizzato con l'ambito del controller.


.

funziona bene per questa direttiva, quando la vista / stato non è nidificato:

jsfiddle / non nidificato / funzionante come previsto

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

Vista:

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

Quando modifico il testo del campo di input, si riflette sull'ambito ...


.

... Ma quando nidivo la vista / stato, il valore sull'ambito mantiene il suo valore iniziale, ma mi aspetto che venga modificato in base al valore del campo di input durante la sovrascrittura.

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

Vista:

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

Qui, il testo sull'ambito (vedi controller) rimane lo stesso.

Qualche idea come posso ottenere lo stesso risultato con le viste nidificate come nel primo esempio?

PS: la direttiva deve rimanere riutilizzabile

jsfiddle / annidato / non funzionante come previsto

È stato utile?

Soluzione

Questo è legato a un problema comune.Come menzionato in questo video angolare js - best practice (29:19) e spiegato qui: Scope annidati in JS angolare

.

"Ogni volta che hai il modello NG, è necessario essere un punto lì da qualche parte. Se non hai un punto, lo stai facendo male."

Quindi il controller dovrebbe creare un oggetto:

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 il modello dovrebbe funzionare con un oggetto con proprietà value:

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

The Dated jsfiddle

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top