2013-05-11 80 views
1

我正在学习angularjs,并且在理解这个概念的工作原理时遇到了一些麻烦。AngularJs和ngResource范围

在控制器我有以下几点:

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 fyi)。

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

我的形式是在一个模板(使用超薄)

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'); 
    }]); 

这里是我的轨道索引页开始聚会: 其正义:

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

任何帮助或链接到文档,可能我错过了(或误解)将是真棒!

+0

形式在哪里,你如何填充它(它如何连接到范围)? – Thilo 2013-05-11 05:46:06

+1

我在主帖中添加了表单。 – jacklin 2013-05-11 05:52:50

+0

你是否在使用'$ routeProvider'和'ngView'?如果是这样,我们可以看到你的Angular路线吗? – 2013-05-11 06:01:04

回答

1

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

Whenver $routeProvider为您更改路由并创建控制器实例,您的旧控制器将消失 - 因此,当您更改URL(新控制器获取其自己的作用域)时,您将丢失$scope上的数据。

为了解决这个问题,你可以在到达控制器加载用户:

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; 
}; 
+0

非常感谢您的帮助! 在尝试此操作之前,我注意到如果我做了一个(href ='#/ customers/{{customer.id}}/edit'),并且提供程序路由到editCustomerController,那么Customer.get将工作并填充表单做$ scope.selected_customer = resource.customer。尽管如此,该var仍然在其他控制器方法中不可用。再次感谢! – jacklin 2013-05-11 17:28:25