【问题标题】:ui-sref blocked from accessing controller data or viewui-sref 被阻止访问控制器数据或视图
【发布时间】:2015-12-04 15:29:57
【问题描述】:

我在获取状态参数的控制器时遇到了一些问题。我正在使用正确的状态链接到下一个视图。

 <td><a ui-sref="orders({customerId: cust.id})">View Orders</a></td>

在我的配置文件中,我引用了该名称和路由参数的状态。我现在注释掉了解析对象。我的目标是进入控制器,然后传递正确的数据。 请注意,我使用的是 controllerAs

我最初的想法是 ({customerId: ctrl.cust.id }) 但是这并没有改变 url 路由。 url 正在更改以匹配 url 名称,但没有连接到控制器,也没有给我视图。

    (function() {
        'use strict';

        angular
            .module('app.orders')
            .config(config);

        function config($stateProvider) {
            $stateProvider
                .state('orders',{
                    // params: {customerid: null},
                    url:'/customers:customerId', 
                    templateUrl: './components/orders/orders.html',
                    controller: 'OrdersController',
                    controllerAs: 'ctrl',
                    resolve: {
                    customerFactory: 'customerFactory',
                    customerInfo: function( customerFactory, $stateParams) {
                    return customerFactory.getCustomers($stateParams.id);
                }

            }

************** 我的主要问题是解决方法。这阻止我进入下一个控制器。 *****************

                    resolve: {
                        customerId:[ '$stateParams','customerFactory', function( $stateParams, customerFactory) {
                             return customerFactory.getCustomers($stateParams.id);
                         }]
                     }
            })
        };
})();

目前我的控制器非常小。我只想连接到它。我检查了我的网络选项卡并查看文件的 GET

  (function() {
    // 'use strict';
    angular
        .module('app.orders')
        .controller('OrdersController', OrdersController);

    function OrdersController($stateParams) {
        console.log('in');
            var vm = this;
            vm.title = "Customer Orders";
            vm.customer = null;
    }
}());

我在主 javascript 文件中引用了我的模块。

   (function () {
    'use strict';

    angular.module('app', ['app.services',
        'app.customers',
        'app.orders','ui.router']);
})();

当我注释掉解析时,我可以访问控制器。所以我知道问题正在解决中。这是我的服务。我正在使用 $http 请求并使用 .then

向 Json 文件发出请求

更新 这是我重构的服务调用,我每次都在控制台中找回正确的客户。

  (function() {
    angular
        .module('app.services',[])
        .constant('_', window._)
        .factory('customersFactory', customersFactory);

    function customersFactory($http, $log) {

        return {
            getCustomers: getCustomers,
            getCustomer: getCustomer
        };
        function getCustomers(){
            return $http.get('./Services/customers.json',{catch: true})
                .then(getCustomerListComplete)
                .catch(getCustomerListFailed);

                function getCustomerListComplete(response) {
                    console.log('response.data',response.data);
                    return response.data;
                }

                function getCustomerListFailed(error) {
                    console.log('error', error);
                }
        }

        function getCustomer(id) {
            var url = './Services/customers.json';
            return $http.get(url, {
                catch: true
            })
            .then(function(response) {
                console.log('promise id',id);
                var data = response.data;
                for(var i =0, len=data.length;i<len;i++) {
                    console.log('data[i].id',data[i].id);
                    if(data[i].id === parseInt(id)) {
                        console.log('data[i]', data[i]);
                        return data[i];
                    }
                }
            })
        }
    }
}());

【问题讨论】:

    标签: javascript angularjs angular-ui-router ui-sref


    【解决方案1】:

    有一个working example with your code

    很难猜出哪里出了问题。根据我在这里给你的建议Have a expression error in ui-sref ...你的代码似乎完全有效。 p>

    我把你的东西放到了这个app.orders.js 文件中(唯一的变化是templateUrl 路径,只是为了plunker 的目的)

    angular
      .module('app.orders', ['ui.router'])
    
    
    'use strict';
    
    angular 
        .module('app.orders')
        .config(['$stateProvider', config]); 
    
    //config.$inject = ['$stateProvider'];
    function config($stateProvider) {
        $stateProvider
            .state('orders',{
                // params: {customerid: null},
                url:'/customers:customerId', 
                //templateUrl: './components/orders/orders.html',
                templateUrl: 'components/orders/orders.html',
                controller: 'OrdersController',
                controllerAs: 'ctrl'
                // resolve: {
                //     customerId:[ '$stateParams','customerFactory', function( $stateParams, customerFactory) {
                //         return customerFactory.getCustomers($stateParams.id);
                //     }]
                // }
        })
    };
    
    
    // 'use strict';
    angular
        .module('app.orders')
        .controller('OrdersController', OrdersController);
    
    OrdersController.$inject = ['$stateParams'];
    function OrdersController($stateParams) {
        console.log('in');
            var vm = this;
            vm.title = "Customer Orders " + $stateParams.customerId;
            vm.customer = null;
    }
    

    这是工作模板components/orders/orders.html

    <div >
      <h3>current state name: <var>{{$state.current.name}}</var></h3>
    
      <h5>title</h5>
      <pre>{{ctrl.title}}</pre>
      ...
    

    当我这样称呼它时:

    <li ng-repeat="cust in [{id:1}, {id:2}]"
        ><a ui-sref="orders({customerId: cust.id})">View Orders - cust ID == {{cust.id}}</a>
    </li>
    

    查看action here

    【讨论】:

    • @HarshMehta,你为什么认为这是错误的?我检查并工作了.. (小记,大多数欧洲名字是First是FirstName,Last是LastName)
    • @Steve k,我在现有代码中也没有发现任何钓鱼的东西。在绝对状态重定向中可能存在一些问题。你检查过从 ui-sref 生成的 html 吗?是不是如你所愿,见this
    • @RadimKöhler。感谢您的帮助,我知道您之前曾尝试帮助我解决此问题。我遇到的问题是使用我在客户路线上创建的视图 {}。我从我的代码中删除了它,我将不得不阅读更多关于绝对路由的内容,以了解如何在这种关系中正确使用视图。
    【解决方案2】:

    所以,虽然 my previous answer 打算让状态在没有解析的情况下工作,但现在我们将观察一些调整(和一个修复)以使解析正常工作。

    a working plunker,扩展了前一个。

    修复

    唯一的修复,最重要的变化来自这个定义:

    angular
        .module('app.services',[])
        .factory('customersFactory', customersFactory);
    

    查看工厂名称中的复数形式,即“客户s工厂”。在这里:

    ...我的主要问题是解决方法。这阻碍了我进入下一个控制器。...

    resolve: {
      customerId:[ '$stateParams','customerFactory', function( $stateParams, customerFactory) {
        return customerFactory.getCustomers($stateParams.id);
      }]
    }
    

    我们要求'customerFactory'(单数,中间没有s

    一些改进:

    所以,这将是我们调整后的状态定义:

    $stateProvider
        .state('orders',{
            // INTEGER is here used to later easily use LO_DASH
            url:'/customers{customerId:int}', // int is the type
            templateUrl: './components/orders/orders.html',
            controller: 'OrdersController',
            controllerAs: 'ctrl',
            resolve: {
              // wrong name with 's'
              //customerId:[ '$stateParams','customerFactory', 
              // we use customer, because we also changed the factory 
              // implementation - to return customer related to 
              // $statePrams.customerId
              customer:[ '$stateParams','customersFactory', 
                function( $stateParams, customersFactory) {
                  return customersFactory
                    //.getCustomers($stateParams.id)
                    .getCustomer($stateParams.customerId)
                    ;
                }]
              }
    })
    

    现在,这是我们调整后的工厂,以及它的新方法getCustomer

    angular
      .module('app.services', [])
      .factory('customersFactory', customersFactory);
    
    customersFactory.$inject = ['$http', '$log', '$q', '$stateParams'];
    
    function customersFactory($http, $log, $q, $stateParams) {
    
      return {
        getCustomers: getCustomers,
        getCustomer: getCustomer
      };
    
      function getCustomers() {
        // see plunker for this, or above in question
      }
    
      // new function
      function getCustomer(id) {
        var url = "customer.data.json";
        return $http
          .get(url, {
            catch: true
          })
          .then(function(response){
            var data = response.data;
            var customer = _.find(data, {"id" : id});
            return customer;
          })
          ;
      }
    }
    

    这是我们的 data.json:

    [
      {
        "id" : 1, "name": "Abc", "Code" : "N1"
      },
      {
        "id" : 2, "name": "Def", "Code" : "N22"
      },
      {
        "id" : 3, "name": "Yyz", "Code" : "N333"
      }
    ] 
    

    这里我们有控制器

    OrdersController.$inject = ['$stateParams', 'customer'];
    function OrdersController($stateParams, customer) {
        console.log('in');
            var vm = this;
            vm.title = "Customer Orders " + $stateParams.customerId;
            vm.customer = customer;
    }
    

    一个视图向客户展示

    <h3>customer</h3>
    <pre>{{ctrl.customer | json}}</pre>
    

    查看here in action

    【讨论】:

    • 再次感谢。你真的很有帮助。我发现了错字并修复了它。我将 lodash 作为常量注入(不确定是否有必要)。在 getCustomer 的承诺中,我仍然得到所有实例。我对 _.find 的印象是找到与传入的给定 id 的匹配项。但是,这似乎返回 undefined。
    • 你能改变我的 plunker 来显示这个问题吗?如果您愿意,我随时准备提供帮助...请 - 我使用 lo-dash 的实现只是为了演示 GetById(id) .. 在该示例中。由你决定,如何通过 ID 获取。可以是特殊的API服务方式,直接消费ID,只返回一个对象。我的方法只是让它变得简单......
    • 好的,这就是我设置服务的方式。我在服务中获得了正确的客户信息,这正是我想要的。我正在尝试将其发送给控制器。但是,我越来越不确定。 plnkr.co/edit/4JOSaJ?p=info
    • 我已经解决了我的决心!!!我没有在控制器中正确引用客户。感谢@Radim 的帮助。
    • 很高兴看到这一进展。祝史蒂夫好运,角度和主要使用 UI-Router ;)
    猜你喜欢
    • 2017-04-26
    • 2015-03-18
    • 2018-12-20
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-08
    • 2021-11-03
    相关资源
    最近更新 更多