Reputation: 15311
I have a hypothetical question. Say I have two object arrays in my Controller and in my view I loop through the data of one of these object arrays. Now is it possible for me to switch the value of this ng-repart (or change the expression) in a directive. For example...
here is my controller:
controller('MainCtrl', ['$scope', function($scope) {
$scope.beatles = [{id:1, name: "John", inst: "Guitar", alive: false},{id:2, name: "Paul", inst: "Bass", alive: true},{id:3, name: "George", inst: "Guitar", alive: false},{id:4, name: "Ringo", inst: "Drums", alive: true}];
$scope.huskers = [{id:1, name: "Bob", inst: "Guitar", alive: true},{id:2, name: "Grant", inst: "Drums", alive: true},{id:3, name: "George", inst: "Bass", alive: true}];
}])
Here is my view...
<div data-my-template-dir class="beatles">
<div data-ng-repeat="beatle in beatles track by $index">
Name: {{beatle.name}}, Instrument: {{ beatle.inst }}
</div>
</div>
Here is my directive...
restrict: 'A',
link: function (scope, element) {
element.bind('click', function () {
console.log('i am clicked');
element[0].children[0].setAttribute('data-ng-repeat','beatle in huskers track by $index');
// something should go here... like scope.apply() ????
});
Now, it seems that the directive does work with the model/ctrl... but the HTML doesn't seem to update in the view... am I going about this wrong, can I update the ng-repeat in the directive?
I have a plunker (or jsbin) here: https://jsbin.com/fasako/edit?html,output
Upvotes: 1
Views: 70
Reputation: 8446
OK, so I have a couple of comments.
First, I think there is a better to accomplish what you want. Instead of editing the markup, in order for angular to reprocess the markup, in order for it to load different data into memory, in order to put it's own processed markup on the screen.... while making for a remarkable run-on sentence probably isn't the best programming decision.
I'd suggest just having one object with all of your data, then have an ng-click
item which chooses which array to process in the ng-repeat
.
I came up with the following example.
angular.module('myModule',[])
.directive('myTemplate', function() {
return {
restrict: 'A',
template:
'<div ng-repeat="item in lists[listSelected] track by $index">' +
'Name: {{item.name}}, Instrument: {{ item.inst }}' +
'</div>',
controller: 'myTemplateCtrl'
};
})
.controller('myTemplateCtrl', ['$scope', function($scope) {
$scope.listSelected = 'beatles';
$scope.lists =
{
beatles:
[
{ id:1, name: "John", inst: "Guitar", alive: false },
{ id:2, name: "Paul", inst: "Bass", alive: true },
{ id:3, name: "George", inst: "Guitar", alive: false },
{ id:4, name: "Ringo", inst: "Drums", alive: true }
],
huskers:
[
{ id:1, name: "Bob", inst: "Guitar", alive: true },
{ id:2, name: "Grant", inst: "Drums", alive: true },
{ id:3, name: "George", inst: "Bass", alive: true }
]
}
;
// this should only be bound to scope once the arrays exist
$scope.changeSelection = function() {
$scope.listSelected = $scope.listSelected === 'beatles' ? 'huskers' : 'beatles';
};
}]);
body {
font-family: "Comic Sans MS", "Lucida Sans Unicode", "Lucida Grande", sans-serif;
}
.beatles {
padding: 10px;
border: 1px solid lightblue;
background-color: aliceblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myModule">
<div my-template ng-click="changeSelection()" class="beatles"></div>
</div>
Upvotes: 1
Reputation: 8920
You have to use $compile
to compile again your ng-repeat
and then append it to the DOM
Something like:
element[0].children[0].setAttribute('data-ng-repeat','beatle in huskers track by $index');
newRepeat = element[0].children[0].html()
template = $compile(newRepeat)($scope)
element.children[0].replaceWith(template)
Upvotes: 0