尝试让一个子视图使用ui-router调用另一个子视图

时间:2015-01-18 23:32:29

标签: angularjs typescript angular-ui-router

我有两个子视图,一个用于类别,一个用于产品,因此该类别的产品。我希望用户能够选择一个类别并查看该类别的所有产品。

所以当在类别行上点击View按钮时,我在类别控制器中调用一个函数。

这是功能:

   self.$scope.viewSalonProducts = function (categoryNumber: string) {
       alert(categoryNumber + "   " + self.dataSvc);
       self.dataSvc.category = categoryNumber;
       self.state.go("salonproducts");
   }

这是我的州定义:

   .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' }
           }
     })

在我的html文件中,这是我定义按钮的方式:

   <input type="button" name="edit" value="View" class="btn btn-default" ng-click="viewSalonProducts(x)" />

如果它有任何不同,这是我对此观点的顶视图:

Categories
<div ui-view="saloncategories"></div>
Products
<div ui-view="salonproducts"></div>

我的产品控制器定义为此,所以

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();
    }
}

因此,如果用户点击该按钮,我想将类别名称(我的按钮x中的ng-click的值)传递给产品控制器,然后让它调用webservice获取并显示信息。

它会使scope.watchhttps://docs.angularjs.org/api/ng/type/ $ rootScope.Scope,然后我只需要看看如何将类别放在产品控制器的范围内。

1 个答案:

答案 0 :(得分:3)

使用UI-Router,我们不必使用$scope.watch list-detail 视图之间进行通信。

这里的原生UI-Router解决方案是使用 paren-child state 定义。所以,州定义应该是:

.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' 
          }
       }
 })

这将是新的控制器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'];
}

这样我们就可以把它挂钩到angularjs:

angular
   .module('MyModule')
   .controller('SalonProductCntrl', SalonProductCntrl); 

这只是一个drafte版本,但这里的重点是 - 将列表视图(用户选择项目ID)和详细信息视图拆分为分离状态。

好处应该是明确的,因为productId的任何变化都会触发新的状态转换。子数据将被更改(更新),而列表将保持不变...这是UI路由器的本质,我会说