angularjs - Access child scope corresponding to a model variable -
i have list of items , i've rendered them in template via ng-repeat
. each of them controlled itemcontroller
exposes behavior item (e.g. grabing focus). here html:
<body ng-controller="maincontroller"> <button ng-click="additem()">add</button> <ul> <li ng-repeat="item in items" ng-controller="itemcontroller"> <div ng-if="item.isediting"> <input ng-model="item.name"/> <button ng-click="item.isediting=false">done</button> </div> <span ng-if="!item.isediting">{{item.name}}</span> </li> </ul> </body>
in maincontroller
, have function adding new item items. here code maincontroller:
app.controller('maincontroller', function($scope){ $scope.items = [ { name: "alireza" }, { name: "ali" } ]; $scope.additem = function(){ $scope.items.push({isediting: true}); } });
whenever add together item items
array, corresponding li
element added view controlled instance of itemcontroller
, , corresponding model new item i've added (or maybe scope
of itemcontroller
, contains item).
when add together item items
, have access item
, not scope of created item. can't run function (like grabfocus) on scope of new item. semantically wrong in design? canonical approach problem?
here plunker link related comments
you can utilize $broadcast
parent scope, along $on
kid scope, notify kid scopes of newly added item. , passing (as argument) $id
of kid scope corresponds newly added item, each kid catching event can know whether or not it's 1 needs have grabfocus()
called.
here's fork of plunker uses approach. wasn't sure trying accomplish $element.find(":text").focus();
in original plunker, tweaked toggle $scope
property in turn controlled style in view. newly added item reddish (by calling own grabfocus
function toggle flag true
), , others black (by calling own losefocus
function toggle flag false
).
modified html (just repeated li
):
<li ng-repeat="item in items" ng-controller="itemcontroller"> <div ng-if="item.isediting"> <input ng-model="item.name"/> <button ng-click="item.isediting=false;handleitemadded($index);">done</button> </div> <span ng-if="!item.isediting" ng-style="{ color: isfocused ? 'red' : 'black' }">{{item.name}}</span> </li>
full javascript:
var app = angular.module("app",[]); app.controller('maincontroller', function($rootscope, $scope){ $scope.items = [ { name: "alireza" }, { name: "ali" } ]; $scope.additem = function(){ $scope.items.push({isediting: true}); }; $scope.handleitemadded = function (index) { // $rootscope.$broadcast('item-added', { index: index }); for(var cs = $scope.$$childhead; cs; cs = cs.$$nextsibling) { if (cs.$index === index) { $rootscope.$broadcast('item-added', { id: cs.$id }); break; } } }; }); app.controller('itemcontroller', function($scope, $element){ $scope.$on('item-added', function (event, args) { if ($scope.$id === args.id + 1) { $scope.grabfocus(); } else { $scope.losefocus(); } }); $scope.grabfocus = function() { $scope.isfocused = true; }; $scope.losefocus = function() { $scope.isfocused = false; }; });
angularjs model-view-controller angularjs-scope angularjs-ng-repeat
No comments:
Post a Comment