2012-06-18 30 views
13

Về hệ thống định tuyến Ember.js mới (được mô tả here), nếu tôi hiểu chính xác, chế độ xem sẽ bị hủy khi bạn thoát khỏi tuyến đường.Cách * không * để hủy Chế độ xem khi thoát khỏi tuyến đường trong Ember.js

Có cách nào để bỏ qua việc hủy chế độ xem khi thoát khỏi tuyến đường để trạng thái của chế độ xem được giữ nguyên khi người dùng nhập lại tuyến đường không?


Cập nhật: Có vẻ như, chế độ xem không bị hủy trừ khi chế độ xem cửa hàng đang được thay thế trong tuyến đường mới. Ví dụ: nếu bạn đang ở trong tiểu bangA với ViewA trong một số {{outlet master}} và bạn chuyển đến stateB với ViewB trong {{outlet master}}, thì ViewB sẽ thay thế ViewA. Cách này là xác định nhiều cửa hàng khi bạn cần phải giữ nguyên các chế độ xem, ví dụ: {{outlet master1}}, {{outlet master2}}, ...

Tính năng đẹp sẽ là khả năng truyền một mảng quan điểm cho cửa hàng. Và cũng có thể chọn xem lượt xem sẽ bị hủy hoặc chỉ bị ẩn, khi thoát khỏi tuyến đường.

+5

Zack, Tôi nghĩ rằng bạn có thể thực hiện những tính năng bổ sung nếu bạn thực hiện mức cửa hàng hàng đầu của bạn một 'ContainerView'. Sau đó, bạn có thể trực tiếp thao tác với trẻ em, thông qua thuộc tính 'childViews' và kiểm soát nếu chế độ xem con bị xóa hoặc chỉ bị ẩn. –

Trả lời

9

Tôi đã tìm ra cách sửa đổi hệ thống định tuyến để các chế độ xem được chèn vào các cửa hàng không bị hủy. Trước tiên tôi ghi đè lên các helper tay lái outlet, để nó tải một Ember.OutletView vào {{outlet}}:

Ember.Handlebars.registerHelper('outlet', function(property, options) { 
    if (property && property.data && property.data.isRenderData) { 
    options = property; 
    property = 'view'; 
    } 

    options.hash.currentViewBinding = "controller." + property; 

    return Ember.Handlebars.helpers.view.call(this, Ember.OutletView, options); 
}); 

đâu Ember.OutletView kéo dài Ember.ContainerView như sau:

Ember.OutletView = Ember.ContainerView.extend({ 
    childViews: [], 

    _currentViewWillChange: Ember.beforeObserver(function() { 
     var childViews = this.get('childViews'); 

      // Instead of removing currentView, just hide all childViews 
      childViews.setEach('isVisible', false); 

    }, 'currentView'), 

    _currentViewDidChange: Ember.observer(function() { 
     var childViews = this.get('childViews'), 
      currentView = this.get('currentView'); 

     if (currentView) { 
      // Check if currentView is already within childViews array 
      // TODO: test 
      var alreadyPresent = childViews.find(function(child) { 
       if (Ember.View.isEqual(currentView, child, [])) {   
        return true; 
       } 
      }); 

      if (!!alreadyPresent) { 
       alreadyPresent.set('isVisible', true); 
      } else { 
       childViews.pushObject(currentView); 
      } 
     } 
    }, 'currentView') 

}); 

Về cơ bản chúng tôi ghi đè _currentViewWillChange() và chỉ ẩn tất cả childViews thay vì loại bỏ số currentView. Sau đó, trong _currentViewDidChange(), chúng tôi kiểm tra xem currentView có nằm trong số childViews và hành động tương ứng hay không. Các Ember.View.isEqual là một phiên bản sửa đổi của Underscore isEqual:

Ember.View.reopenClass({ 
    isEqual: function(a, b, stack) { 
     // Identical objects are equal. `0 === -0`, but they aren't identical. 
     // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal. 
     if (a === b) return a !== 0 || 1/a == 1/b; 
     // A strict comparison is necessary because `null == undefined`. 
     if (a == null || b == null) return a === b; 
     // Unwrap any wrapped objects. 
     if (a._chain) a = a._wrapped; 
     if (b._chain) b = b._wrapped; 
     // Compare `[[Class]]` names. 
     var className = toString.call(a); 
     if (className != toString.call(b)) return false; 

     if (typeof a != 'object' || typeof b != 'object') return false; 
     // Assume equality for cyclic structures. The algorithm for detecting cyclic 
     // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. 
     var length = stack.length; 
     while (length--) { 
      // Linear search. Performance is inversely proportional to the number of 
      // unique nested structures. 
      if (stack[length] == a) return true; 
     } 
     // Add the first object to the stack of traversed objects. 
     stack.push(a); 
     var size = 0, result = true; 
     // Recursively compare objects and arrays. 
     if (className == '[object Array]') { 
      // Compare array lengths to determine if a deep comparison is necessary. 
      size = a.length; 
      result = size == b.length; 
      if (result) { 
       // Deep compare the contents, ignoring non-numeric properties. 
       while (size--) { 
        // Ensure commutative equality for sparse arrays. 
        if (!(result = size in a == size in b && this.isEqual(a[size], b[size], stack))) break; 
       } 
      } 
     } else { 
      // Objects with different constructors are not equivalent. 
      if (a.get('constructor').toString() != b.get('constructor').toString()) { 
       return false; 
      } 

      // Deep compare objects. 
      for (var key in a) { 
       if (a.hasOwnProperty(key)) { 
        // Count the expected number of properties. 
        size++; 
        // Deep compare each member. 
        if (!(result = b.hasOwnProperty(key))) break; 
       } 
      } 
     } 
     // Remove the first object from the stack of traversed objects. 
     stack.pop(); 
     return result; 
    } 
}); 
+1

Một containerView là cách đầy đủ hơn thay vì đặt tất cả các logic tùy chỉnh này trong (mà theo một cách là một bản sao thô của containerView). Đây không phải là giải pháp được chấp nhận. – Valer

+1

Đây là chế độ xem vùng chứa và lôgic này không may là (vẫn cần) để ngăn chặn xem teardowns. – runspired

4

Để trạng thái của chế độ xem được giữ nguyên khi người dùng nhập lại tuyến đường .

Thay vào đó, lưu trữ thông tin đó trong bộ điều khiển (hoặc trình quản lý nhà nước) để khi tuyến đường được nhập lại, chế độ xem mới được khởi tạo với trạng thái cũ. Điều đó có ý nghĩa? Vì vậy, ví dụ, nếu đó là danh sách các bài đăng và một danh sách bài đăng được chọn, bạn sẽ lưu trữ dữ liệu về bài đăng nào được chọn trong bộ điều khiển (hoặc trình quản lý trạng thái). Sau khi truy cập một bài đăng cụ thể và sau đó quay lại danh sách, cùng một bài đăng đó sẽ được chọn.

Tôi có thể hình dung một trường hợp sử dụng, điều này sẽ không hữu ích (ví dụ: cuộn đến vị trí cụ thể trong danh sách dài) để có thể không trả lời được câu hỏi của bạn.

+0

Có, tôi không nói về một lựa chọn đơn giản, nhưng trường hợp bạn có thể có một biểu mẫu dài mà người dùng đã hoàn thành một phần, cuộn vị trí danh sách dài (như bạn đã nói) ... Vì vậy, nó không có ý nghĩa lưu trữ tất cả thông tin đó vào bộ điều khiển và cập nhật chế độ xem khi nhập lại. Một cách khác là lưu trữ trường hợp Xem trong bộ điều khiển và sử dụng mỗi lần bạn nhập tuyến. Nhưng tôi hy vọng rằng có một cách tốt hơn. –

+0

Có thể có một cách tốt hơn: ai đó biết Ember tốt hơn tôi (có rất nhiều) có thể trả lời. :) – pjmorse

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