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

Trying to have one subview call another subview using ui-router

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

因此,当在类别行上单击 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();
    }
}

因此,如果用户单击按钮,我想将类别名称(即按钮 ng-clickx 的值)传递给产品控制器,然后让它调用用于获取和显示信息的网络服务。

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

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

这里的本地 UI-路由器解决方案是使用 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); 

这只是一个草稿版本,但这里的要点是 - 将列表视图(其中用户 select 项目 ID)和详细视图 - 拆分为不同的状态。

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