In my highest level scope, I fetch some data from the server for use throughout the page like this: $scope.lotsOfData = $http.get("lotsOfData");
. So now my scope holds a promise object for lotsOfData
. Then, in my HTML, I have directives that are only concerned with a small set of the lotsOfData
object. One such directive could look something like this:
<div>
{{lotsOfData.foo.blah[source].bar[id].someData}}<br>
{{lotsOfData.foo.blah[source].bar[id].otherData}}<br>
{{lotsOfData.foo.blah[source].bar[id].differentData}}
</div>
where source and id are being set through attributes on the directive. My HTML page then looks something like this:
<data-subset source="1" id="1" />
<data-subset source="1" id="2" />
<data-subset source="2" id="1" />
<data-subset source="3" id="1" />
I hate having to repeat lotsOfData.foo.blah[source].bar[id]
throughout the directive. Is there any way to set in the scope so my directive could look more like this?
<div>
{{currObj.someData}}<br>
{{currObj.otherData}}<br>
{{currObj.differentData}}
</div>
Not only does this clean up the HTML, but if we ever restructure that lotsOfData
object, there's be only one place to change how it's getting the currObj
object. In the link function for my directive I tried this:
link: function(scope, element, attrs) {
scope.currObj = scope.lotsOfData.foo.blah[attrs.source].bar[attrs.id];
}
However, since lotsOfData
is a promise object, it doesn't have a property called foo
. I don't know a whole lot about how the promise object works, so maybe I just need to know how I can get to the properties I need.
I hope what I'm trying to accomplish here makes sense and someone could point me in the right direction as to how to make this work. Thanks.
link: function(scope, element, attrs) {
scope.$watch('lotsOfData.foo.blah['+attrs.source+'].bar['+attrs.id+']', function(newVal, oldVal) {
scope.currObj = newVal;
}
}
This should fix the problem, you will simply watch for changes on your data and set the currObj
with the new value.
This is how I accomplished what I wanted to. I created an outer directive to the one mentioned above and then created an isolated scope for the inner directive that bound to the data I wanted.
So my outer directive HTML looks like this:
<div>
<data-subset curr-obj="lotsOfData.foo.blah[source].bar[id]"></data-subset>
</div>
And the javascript looks like this:
myModule.directive('outer-data', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'outerData.html',
link: function(scope, element, attrs) {
scope.id = attrs.id;
scope.source = attrs.source;
},
scope: true
}
});
Then the javscript for my dataSubset looks like this:
myModule.directive('dataSubset', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'dataSubset.htm',
scope: {
currObj: '='
}
}
});
So then in my top-level HTML file I have something like this:
<outer-data source="1" id="1" />
<outer-data source="1" id="2" />
<outer-data source="2" id="1" />
<outer-data source="3" id="1" />
And I can just reference currObj on my dataSubset like I wanted.