2013-04-17 21 views
9

Tôi có ứng dụng Góc sử dụng Breeze và có một EntityManager dùng chung cho các bộ điều khiển khác nhau của tôi. Có thể tiếp cận một vài bộ điều khiển của tôi mà không cần thực hiện truy vấn để điền trước MetadataStore của EntityManager. Tôi đã tìm thấy phần nào của hướng bắt đầu here để tìm nạp siêu dữ liệu ở đầu ứng dụng. Dự án của tôi dựa trên mẫu Angular-Breezejs và khi tôi thử làm như sau, tôi nhận được lỗi vì lời hứa không được giải quyết hoàn toàn trước khi một cái gì đó sử dụng datacontext.Breezejs, Cách lấy siêu dữ liệu khi bắt đầu với EntityManager được chia sẻ

app.factory('datacontext', 
    ['breeze', 'Q', 'model', 'logger', '$timeout', 
     function (breeze, Q, model, logger, $timeout) { 
      logger.log("creating datacontext"); 

      configureBreeze(); 
      var manager = new breeze.EntityManager("/api/app");    
      manager.enableSaveQueuing(true); 

      var datacontext = { 
       metadataStore: manager.metadataStore, 
       saveEntity: saveEntity, 
       getUsers: getUsers, 
       getUser: getUser, 
       createUser: createUser, 
       deleteUser: deleteUser 
      }; 

      return manager.fetchMetadata() 
        .then(function() { 
         model.initialize(datacontext); 
         return datacontext; 
        }) 
        .fail(function (error) { 
         console.log(error); 
         return error; 
        }); 
      //Function definitions 

Cách thích hợp để chặn cho đến khi tìm nạp siêu dữ liệu hoàn tất là gì? Vì có vẻ như không cần thiết phải kiểm tra xem siêu dữ liệu có tồn tại trước mỗi chức năng không phải truy vấn (bao gồm tạo đối tượng) như áp phích gốc của câu hỏi được liên kết ở trên đã kết thúc hay không.

Trả lời

11

Tôi thấy sự cố của bạn.

Khi Góc gọi hàm sản xuất của bạn để tạo dịch vụ DataContext, nó dự kiến ​​sẽ lấy lại ngay lập tức (đồng bộ) đối tượng DataContext sẵn sàng sử dụng. Nhưng bạn đang trả lại lời hứa để trả lại DataContext vào một thời điểm nào đó trong tương lai ... và Angular không được xây dựng cho điều đó.

Tôi thích ý tưởng đó. Bạn có thể muốn đề xuất nó với nhóm Angular :-).

Vì vậy, những gì bạn đang cố gắng ở đây sẽ không hoạt động. Bạn phải trả lại ngay DataContext. Cho đến khi siêu dữ liệu đến, bạn phải chặn toàn bộ giao diện người dùng hoặc chặn chức năng cụ thể dựa trên siêu dữ liệu (ví dụ: createUser). Nó giống như chờ đợi DOM giải quyết trước khi thao tác với jQuery.

Tình trạng này không phải là góc cụ thể. Bạn phải đối mặt với tình trạng khó khăn tương tự trong một ứng dụng Knockout. Độ phân giải tương tự.

Bắt đầu bằng cách hiển thị một số loại móc "whenReady" trên DataContext. Lời hứa có thể là một ý tưởng hay. Một cái gì đó như thế này:

 
function (breeze, Q, model, logger, $timeout) { 
    logger.log("creating datacontext"); 
    ... 
    var readyDeferred = Q.defer(), whenReady = readyDeferred.promise; 

    var datacontext = { 
      whenReady: whenReady, 
      ... 
     }; 

    initializeDatacontext(); 

    return datacontext; // now Angular is happy because it has a datacontext 

    function initializeDatacontext() { 
     manager.fetchMetadata() 
       .then(function() { 
        readyDeferred.resolve(); 
        // do success stuff; 
       }) 
       .fail(function (error) { 
        readyDeferred.reject(error); 
        // do error stuff; 
       }); 
    } 

    //Function definitions 
} 

Ở những nơi khác trong bootstrapping của ứng dụng, bạn buộc vào lời hứa datacontext.whenReady.

 
    // somewhere inside your main controller 
    $scope.isReady = false; 
    datacontext.whenReady.then(function() { 
      $scope.isReady = true; 
      $scope.$apply(); 
     }) 
    .fail(function() { alert("Uh oh!"); }); 
    ... 

Bây giờ ràng buộc phạm vi isReady vào HTML sao cho bạn nhận được hành vi mong muốn. Bạn có thể sử dụng nó để chặn toàn bộ giao diện người dùng hoặc chỉ đóng dấu chức năng (ví dụ: "Tạo người dùng") cho đến khi văn bản dữ liệu đã sẵn sàng.

Pleae không sử dụng mã giả này theo đúng nghĩa đen. Sử dụng nó cho cảm hứng.

+0

Điều này sẽ được cập nhật. fetchMetadata yêu cầu tham số Dataservice – cecilphillip

+3

Không có thông số nào. Bạn đang nghĩ đến 'MetadataStore.fetchMetadata'. Đây là 'EntityManager.fetchMetadata'. – Ward

Các vấn đề liên quan