问题
I have two subviews, one for category and one for products, so the products for that category. I want a user to be able to select a category and see all the products for that category.
So I am calling a function in the category controller when the View
button is clicked on a category row.
This is the function:
self.$scope.viewSalonProducts = function (categoryNumber: string) {
alert(categoryNumber + " " + self.dataSvc);
self.dataSvc.category = categoryNumber;
self.state.go("salonproducts");
}
This is what my state definition looks like:
.state('master.categoryinfo', {
url: '/categories',
views: {
'': { templateUrl: 'Templates/SalonCategoryMain.html', controller: 'SalonCategoryProductCntrl' },
"saloncategories@master.categoryinfo": { templateUrl: 'Templates/SalonCategoryList.html', controller: 'SalonCategoryCntrl' },
"salonproducts@master.categoryinfo": { templateUrl: 'Templates/SalonProductList.html', controller: 'SalonProductCntrl' }
}
})
And in my html file this is how I define the button:
<input type="button" name="edit" value="View" class="btn btn-default" ng-click="viewSalonProducts(x)" />
And if it makes any difference this is my top view for this view:
Categories
<div ui-view="saloncategories"></div>
Products
<div ui-view="salonproducts"></div>
My products controller is defined as this, so
export class SalonProductCntrl {
private $scope: Extensions.IProductsDisplayScope;
private dataSvc: giftCertDataSvc;
private init(): void {
var self = this;
self.dataSvc.getProductsBySalon().then(function (data) {
self.$scope.products = data;
});
}
constructor($scope: Extensions.IProductsDisplayScope, giftCertDataSvc: giftCertDataSvc) {
this.$scope = $scope;
this.dataSvc = giftCertDataSvc;
this.init();
}
}
So, if a user clicks on the button, I want to pass the category name, which is the value of x
in my button ng-click
to the product controller and have it then call the webservice to get and display the information.
Would it make scope.watch
, https://docs.angularjs.org/api/ng/type/$rootScope.Scope, then I just need to see how to put the category in the scope for the product controller.
回答1:
With UI-Router
we do not have to use $scope.watch
to communicate between list-detail views.
The native UI-Router solution here would be to use the paren-child state defintion. So, the state definition should be like:
.state('master.categoryinfo', {
url: '/categories',
views: {
'': {
templateUrl: 'Templates/SalonCategoryMain.html',
controller: 'SalonCategoryProductCntrl'
},
// these views will be replaced by child state
"saloncategories@master.categoryinfo": {
template: 'here will be category details',
},
"salonproducts@master.categoryinfo": {
template: 'here will be salon product details',
}
}
})
.state('master.categoryinfo.detail', {
url: '/:productId',
views: {
// this notation in a child
// "saloncategories@master.categoryinfo": {
// is the same as this
"saloncategories": {
templateUrl: 'Templates/SalonCategoryList.html',
controller: 'SalonCategoryCntrl'
},
"salonproducts": {
templateUrl: 'Templates/SalonProductList.html',
controller: 'SalonProductCntrl'
}
}
})
And this would be the new controller def:
export class SalonProductCntrl
{
private init(): void
{
this.dataSvc
// here we can pass the product Id
.getProductsBySalon(this.$stateParams.productId)
// here we use arrow function
// which does take care for us about this
.then((data) => {
this.$scope.products = data;
});
}
// this notation will do the same - all params will be private
// available via this.
constructor(private $scope: Extensions.IProductsDisplayScope
, private $stateParams: ng.ui.IStateParamsService
, private giftCertDataSvc: giftCertDataSvc)
{
this.init();
}
static $inject = ['$scope', '$stateParams', 'giftCertDataSvc'];
}
And this way we can hook that into angularjs:
angular
.module('MyModule')
.controller('SalonProductCntrl', SalonProductCntrl);
This is just a drafte version, but the point here is - split the list view (where users select the item ID) and the detail view - into separated states.
Benefit should be clear, because any change of the productId will trigger new state transition. Child data will be changed (updated) while list will stay the same... That's the essence of UI-Router, I'd say
来源:https://stackoverflow.com/questions/28016057/trying-to-have-one-subview-call-another-subview-using-ui-router