2015-01-26 20 views
14

tôi đã nhà máy sau được xác định:

angular.module("account").factory("users",["$http", 
    function(a){ 
     return { 
     getUser: function(){ 
      return a.get("/user/me").then(function(r){ 
       return r.data; 
      }); 
     } 
    }; 
    } 
]); 

Và điều khiển của tôi:

angular.module("test.controllers",["account"]) 
.controller("TestCtrl",["$scope","users", 
    function(a,u){ 
     a.user = u.getUser(); 
     console.log(a.user); 
}]); 

Đây là console.log:

d {$$state: Object, then: function, catch: function, finally: function} $$state: Object status: 1 value: Object user: Object__v: 0 _id: "54c1fg29f36e117332000005" temp: "1ce3793175e0b2548fb9918385c2de09" __proto__: Object __proto__: Object __proto__: Object __proto__: Object 

Trên đây mã đang trả về một đối tượng trạng thái thay vì đối tượng người dùng. Nhưng từ nhật ký, đối tượng trạng thái có đối tượng người dùng trong giá trị. Làm thế nào để tôi có được đối tượng người dùng? Hoặc tôi đang làm điều này hoàn toàn sai?

Tôi biết cách khác là trả lại $ http.get và gọi phương thức then() trong bộ điều khiển. Nhưng tôi sẽ sử dụng đối tượng người dùng thường xuyên và nếu tôi đang gọi phương thức then() trong bộ điều khiển, nó gần giống như sử dụng $ http.get trong bộ điều khiển thay vì nhà máy.

+0

Đối tượng bạn thấy trong console.log là lời hứa được trả về từ cuộc gọi đến .get trong cuộc gọi tới .getUser. Cuộc gọi đến.sau đó tạo ra một lời hứa mới và khi bạn trả lại một cái gì đó từ đó nó sửa đổi dữ liệu được giải quyết cho bất kỳ sau đó. – shaunhusain

+0

kiểm tra câu trả lời này từ tôi từ một bài đăng khác: http://stackoverflow.com/a/38007172/1739949 –

Trả lời

24

JavaScript I/O thường là, kể cả trong trường hợp này là không đồng bộ. Cuộc gọi getUser của bạn trả lại lời hứa $ q . Để Unwrap nó bạn phải chuỗi để nó và sau đó Unwrap nó như vậy:

angular.module("test.controllers",["account"]) 
.controller("TestCtrl",["$scope","users", 
    function(a,u){ 
     u.getUser().then(function(user){ 
      a.user = user; 
      console.log(a.user); 
     }); 
}]); 

Nếu bạn đang sử dụng định tuyến bạn cũng có thể muốn nhìn vào resolve tùy chọn trong các tuyến đường. Xem thêm this related question.

+0

Nhưng nếu tôi đang sử dụng sau đó() trong bộ điều khiển, tôi có thể thoát khỏi nhà máy và chỉ cần kiếm $ http.get ('/ user/me'). sau đó (..) gọi. – wdphd

+4

@wdphd bạn có thể, lý do các cuộc gọi này nằm trong nhà máy và không nằm trong bộ điều khiển bởi vì nó tạo mã gọn gàng hơn - không phải vì ma thuật :) Bất kỳ thứ gì bạn có thể viết trong nhà máy cũng có thể viết bên trong bộ điều khiển 't tạo điều kiện tách rất tốt các mối quan tâm. –

2
angular.module("account").factory("users",["$http", 
    function(a){ 
     var factObj = { 
     user: null, 
     getUser: function(){ 
      return a.get("/user/me").then(function(r){ 
       factObj.user = r.data; 
      }); 
     } 
     factObj.getUser(); 

     return factObj; 
    }; 
    } 
]); 

angular.module("test.controllers",["account"]) 
.controller("TestCtrl",["$scope","users", 
    function(a,u){ 
     a.userService = u; 
}]); 

Theo quan điểm của bạn

<div ng-controller="TestCtrl as test">{{test.userService.user}}</div> 

chỉnh sửa dựa trên ý kiến, đúng điều này sẽ không làm việc với các bộ điều khiển hoặc xem như bạn có thể có họ, nhưng mô hình này hoạt động tốt và loại bỏ sự cần thiết phải có. sau đó trong mọi bộ điều khiển có thể tái sử dụng dữ liệu.

Thông thường lưu trữ mô hình của bạn trong nhà máy hoặc dịch vụ liên quan đến việc tìm nạp dữ liệu giúp đường dẫn dễ dàng hơn để đưa dữ liệu vào mọi chế độ xem bạn cần đến. Phía dưới đây là bạn sẽ tìm nạp người dùng khi nhà máy này được tham chiếu thay vì bắn một cách rõ ràng chức năng getUser từ bộ điều khiển. Nếu bạn muốn nhận được lời nhắc, bạn có thể lưu lời hứa từ lần đầu tiên nó được yêu cầu trong hàm getUser và trả lại lời hứa đó cho tất cả các cuộc gọi tiếp theo nếu nó đã được thiết lập, theo cách này bạn có thể gọi getUser nhiều lần mà không cần lặp lại yêu cầu API.

+0

Điều này vẫn không thành công - vấn đề của OP là sự không đồng bộ của 'get' không phải với nơi dữ liệu được lưu trữ. –

+0

Benjamin Tôi sử dụng mẫu này trong nhiều ứng dụng hoạt động, nó hoạt động tốt miễn là bạn tham khảo dữ liệu thông qua nhà máy trong bộ điều khiển. Ví dụ toàn diện hơn ở đây http://plnkr.co/edit/cqyeXB5WgKZynQZdvEYP?p=preview – shaunhusain

+0

Tất cả những gì bạn phải làm để biết điều này sẽ không hoạt động là đọc mã. 'a.get' trả về lời hứa Promises/A + tuân thủ - nó _must_ để trở thành lời hứa A + trì hoãn việc thực hiện cho chu kỳ tiếp theo. Bạn sẽ gọi 'getUser' sẽ trả lời lời hứa cho none_ và sau đó gọi' .user' sẽ trả về 'null'. Nếu bạn gặp bất kỳ hành vi nào khác, vui lòng gửi lỗi [chống lại trình theo dõi vấn đề] (https://github.com/angular/angular/issues). Hành vi tôi mô tả được xác định rõ. –

0

tôi có ở đây một kịch bản tương tự .. Tôi hy vọng nó sẽ giúp ai đó ...

nhà máy của tôi ..

angular.module('programList.services',[]) 
    .factory('PROGRAMS', function($http) { 
    return { 
     getprogramList: function() { 
     return $http.get('/api/programs/list').then(function(result) { 
     return result.data[0]; 
     }); 
     } 
    }; 
    }); 

Đây là bộ điều khiển của tôi ..

angular.module('programList.services']) 
.controller('tviProgramsController', 
    function($scope,$state,$stateParams,PROGRAMS){ 
     //this is the call to access the list as answered by Benjamin Above using then on success 
     PROGRAMS.getprogramList().then(function(list){ 
        $scope.programlist = list; 
       }); 
    }); 

; 

Đây là trên bộ định tuyến ở phía máy chủ ...

var express  = require('express'), 
    programscontroller = require(path + 'programservercontroller'), 
    router   = new express.Router(); 
    router.get('/api/programs/list', programscontroller.programlist); 

Đây là mô-đun cho cuộc gọi mysql

var con = require('../../database/dbcon'), 
mysql = require('mysql'); 

module.exports.programlist = function(req, res){ 
var data = req.params.data; 
var sql = "CALL `sp_programlist`"; 
    con.query(sql, function(err, result) { 
     if(err){ 
      throw err; 
     } else { 
      res.send(JSON.stringify(result)); 
     } 
    }); 
}; 
Các vấn đề liên quan