1

我正在学习 angularjs,但在理解这个概念的工作原理时遇到了一些麻烦。

在控制器中,我有以下内容:

Customer.get({id: customer_id, action: 'edit', format : 'json'}, function(resource) {
  $scope.selected_customer = resource.customer;
  console.log($scope.selected_customer);
}, function(response) {
});

这行得通。它从服务器端检索数据(我正在使用 rails ),并且 console.log 显示了我的期望。

我遇到问题的概念是访问 $scope.selected_customer。

例如,在下一个案例中,第二个日志不会显示我期望的客户对象,而是它可能是一个承诺的角度对象?(我正在使用不稳定的 1.1.4 仅供参考)。

test = Customer.get({id: customer_id, action: 'edit', format : 'json'}, function(resource) {
  $scope.selected_customer = resource.customer;
  console.log($scope.selected_customer);
}, function(response) {
});

// undefined
console.log($scope.selected_customer);
// angular object b{$resolved: false, $then: function, $get: function, $save: .... }
console.log(test);

因此,如果我想要一个模板来显示有关该客户的信息,此时它是不可能的。

这是完整的控制器。您可以看到我想要检索该对象,然后更改将是用于编辑此选定客户的模板的位置:

function CustomersEditController($scope, $location, Customer) {
  $scope.edit_customer = function(customer_id) {
    Customer.get({id: customer_id, action: 'edit', format : 'json'}, function(resource) {
      $scope.selected_customer = resource.customer;
      $location.path('/customers/' + customer_id_id + '/edit');
    }, function(response) {
      console.log('ERROR');
    });
  };
};

这很好用,只是由于范围问题,它没有使用 selected_customers 属性填充表单。

这是我的服务:

var customer_service = angular.module('customer_service', ['ngResource', 'ui']);

customer_service.factory('Customer', function($resource) {
  return $resource('/customers/:id/:action', {id: '@id'}, {
    update: { method: 'PUT' }
  });
});

我的表格在模板中(使用 slim)

  div.center
    form(ng-submit='submit()' ng-controller='CustomersEditController')
      input(type='text' ng-model='selected_customer.first_name')

我正在使用 routeProvider:

angular.module('customer_app', ['customer_service'])
  .config(['$routeProvider', function($provider) {
    $provider.when('/:customer_id/edit/', { templateUrl: '/assets/customers/edit.html.slim', controller: 'CustomersController' });
  }])
  .config(["$httpProvider", function(provider) {
    provider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content');
  }]);

这是让派对开始的我的 Rails 索引页面:它只是:

div(ng-app="customer_app")
  h1 Customers
    div(ng-view)

任何可能我错过(或误解)的文档的帮助或链接都会很棒!

4

1 回答 1

1

根据您发布的 JavaScript,您的控制器是CustomersEditController. 但是,当您使用 切换 URL 时$location.path,您$routeProvider会加载新路由,CustomersController而是实例化(通过 定义$routeProvider)。

每当$routeProvider为您更改路由并创建控制器实例时,您的旧控制器就会消失 - 因此您在$scope更改 URL 时会丢失数据(新控制器有自己的范围)。

要解决此问题,您可以在到达控制器时加载用户:

function CustomersEditController($scope, $location) {
  $scope.edit_customer = function(customer_id) {
    $location.path('/customers/' + customer_id_id + '/edit');
  };
};

function CustomersController($scope, $location, $routeParams, Customer) {
  var customer_id = $routeParams.customer_id; // from $routeProvider
  Customer.get({id: customer_id, action: 'edit', format : 'json'}, function(resource) {
    $scope.selected_customer = resource.customer;
  }, function(response) {
    console.log('ERROR');
  });
};

当然,在用户 ID 无效的情况下,您必须显示错误或重定向回之前的 URL。

另一种选择是resolve在您的路由配置中使用该属性。基本上,resolve允许您定义新控制器将需要的数据,并且您可以确保在切换到新路由之前所述数据可用并将数据注入新控制器。通过使用promise,您也可以使用异步加载的数据。

$routeProvider.when('/:customer_id/edit/', {
  templateUrl: '/assets/customers/edit.html.slim',
  controller: 'CustomersController',
  resolve: {
    customer: ['$q', '$route', 'Customer', function($q, $route, Customer) {
      var deferred = $q.defer()

      var customer_id = $route.current.params.customer_id;
      Customer.get({id: customer_id, action: 'edit', format : 'json'}, function(resource) {
        // got our user; change routes now
        deferred.resolve(resource.customer);
      }, function(response) {
        // Uh oh! No user found. Cancel changing routes
        // and trigger a $routeChangeError event
        deferred.reject(response);
      });

      // returning the promise ensures the route won't change
      // until the deferred that generated the promise is resolved
      return deferred.promise;
    }]
  }
});

// lower-case customer is injected based on name from `resolve` in route
function CustomersController($scope, $location, customer) {
  $scope.selected_customer = customer;
};
于 2013-05-11T07:11:53.107 回答