0

녹아웃 생성 콘텐츠가 다른 페이지가 있습니다. 오른쪽 메뉴에서 선택한 행에 따라 페이지 중간에 새 데이터를로드해야하는 데이터가 포함 된 올바른 메뉴가 있습니다.전역 변수를 사용하지 않고 knockout.js viewModel 재사용

그래서 페이지 중간에 콘텐츠를 가져올 수 있습니다. 백엔드에서 현재 내용을로드하고 표시합니다. 그러나 오른쪽 패널에서 항목을 선택할 때 ... 페이지 중간의 데이터를 다시 가져 와서 페이지를 업데이트하고 싶습니다. 그러나 이것은 나를위한 중지 지점입니다. 콘텐츠 가져 오기가 네임 스페이스에서 수행되고 전역 변수가 허용되지 않기 때문에 현재 viewModel을 다시 사용할 수 없습니다 (또는 적어도 내가 어떻게 해야할지 모르겠다). 따라서 바인딩을 적용 할 수없는 새로운 viewModel을 만듭니다. 이러한 바인딩은 페이지가로드 될 때 이미 동일한 유형의 viewModel에 적용 되었기 때문에 바인딩에 적용 할 수 없습니다.

<!-- page discussion --> 
<div data-role="page" id="discussion"> 
    <!-- Content --> 
    <div data-role="content"> 
     <!-- ladda replies --> 
     <div id="replies"> 
      <!-- ko foreach: replies --> 
      <div class="message message-first"> 
       <div class="message-header"> 
        <div class="message-header-user"> 
         <h1>Persons Name</h1> 
         <h2>Subtitle</h2> 
        </div> 
        <div class="message-header-date" data-bind="text: Created"></div> 
       </div> 
       <div class="message-content"> 
        <span data-bind="text: Body"></span> 
        <hr /> 
       </div> 
      </div> 
      <!-- /ko --> 
     </div> 
    </div> 
    <!-- panel --> 
    <!-- Grupper --> 
    <div id="nav-panel-discussion-groups" data-role="panel" data-theme="a" data-position="right" data-display="overlay"> 
       <!-- ko foreach: discussions --> 
       <ul class="nav-search" data-role="listview" data-theme="a" data-iconpos="left" data-inset="true"> 
        <li data-role="list-divider" data-swatch="a" data-theme="a" data-form="ui-bar-a"> 
         <div data-type='horizontal'> 
          <label data-bind="text: Title"></label> 
          <a data-bind="attr: { eventId: Id }" eventId="" name='newThread' data-role="button" data-icon='plus' data-inline="true" data-mini="true" data-theme="a" data-iconpos='notext' id="A4">New</a> 
         </div> 
        </li> 

        <!-- ko foreach: Threads --> 
        <li data-mini="true" data-icon="false" data-bind=""> 
         <a href="#discussion" data-bind="text: Title, click: Domain.Discussion.LoadDiscussionReplies2.bind($root.Id, Id)" data-transition="slide"></a> 
        </li> 
        <!-- /ko --> 
       </ul> 
       <!-- /ko --> 
    </div> 
    <!-- /panel --> 
</div> 

내 질문은 : 내가 데이터를 페치 다시와 뷰 모델 번에 시작을 다시 사용할 수있는 방법이 내 HTML 코드가

Function.registerNamespace('Domain.Discussion'); 

$(document).ready(function() { 
    var repliesViewModel = Domain.Discussion.RepliesView.ReplyPage; 

    ko.applyBindings(repliesViewModel, document.getElementById('discussion')); 
}); 

Domain.Discussion.RepliesView = Domain.Discussion.RepliesView || { 
    ReplyPage: (function() { 
     function Reply(data) { 
      var self = this; 
      self.ParentItemId = data.ParentItemID; 
      self.Body = data.Body; 
      self.Created = data.Created; 
     } 
     var onGetRepliesSuccess = function (replies) { 
      var buffer; 
      buffer = $.map(replies.RepliesResult, function (item) { return new Reply(item); }); 
      viewModelReplies.replies(buffer); 
     }; 
     var onGetRepliesError = function (sender, args) { 
      alert(args.message); 
     }; 
     var viewModelReplies = { 
      replies: ko.observableArray([]), 
      loadReplies: function (parentItemId, listId) { 
       if (parentItemId !== null && listId !== null) { 
        console.log("ParentItemId: " + parentItemId + " -- ListId: " + listId); 
        alert("Domain.Discussion.RepliesView"); 

        $.ajax({ 
         url: absolutePath + "api/Replies/" + listId + "/" + parentItemId, 
         headers: { "Accept": "application/json; odata=verbose" }, 
         success: onGetRepliesSuccess, 
         error: onGetRepliesError 
        }) 
       } 
      }, 
     }; 

     viewModelReplies.loadReplies(1, '6a5ed4ad-5a7c-428f-947e-b8aa2de54489'); 

     return viewModelReplies; 
    }()) 
}; 

// The method loaded by the row-click in the right panel. 
Domain.Discussion.LoadDiscussionReplies2 = function (discussionListId, currentItem) { 
    try { 
     if (currentItem.ListId !== "" && currentItem.Id !== "") { 
      // Call the current viewModel and tell it to loadReplies 
      // This doesn't work since global variables are, of course, not allowed 
      repliesViewModel.loadReplies(currentItem.Id, currentItem.ListId); 
     } 
    } 
    catch (e) { 
     alert(e); 
    } 
} 

입니다 :

이 내 JS 코드 페이지로드. 나는 지금 완전히 붙어있다.

+0

나는 상황을 잘 모르겠다. 매번 인스턴스화 할 필요없이 다른 뷰 모델의 뷰 모델을 업데이트하려고합니까? – NilsH

+0

예, 맞습니다. 나는 그것이 내가하려는 일이라고 믿는다. –

답변

1

현재 프로젝트에서 비슷한 요구 사항이 있습니다. 우리는 같은 페이지에 여러 개의 뷰 모델을 가지고 있으며 하나의 뷰 모델에있는 액션은 다른 뷰 모델 중 하나 (또는 ​​그 이상)의 상태에 영향을 줄 수 있습니다. 모든 뷰 모델이 공유하는 EventEmitter 버스를 사용하여 문제를 해결했습니다. 따라서 viewmodel 중 하나가 새로운 데이터를 받으면이 이벤트를 수신하는 다른 뷰 모델로 이벤트로 보냅니다. 이런 식으로 뭔가가 :

// Data fetched 
eventBus.emit('mynamespace:data', [data]); 

그리고 다른 뷰 모델에

:

// Respond to data 
eventBus.on('mynamespace:data', function(data) { 
    // Process data and update viewmodel state 
} 

그래서 공통의 유일한 이벤트 버스입니다. 그들에게는 서로에 대한 다른 지식이 없습니다.

+0

다음은 슈퍼 라이트 웨이트 펍/서브입니다. 문자열 대신 "유형이 지정된"메시지가 사용됩니다. http://jsfiddle.net/wJtun/3/ – Anders

+0

NilsH - EventEmitter에 대한 몇 가지 코드 예가 ​​있습니까? –

+0

내가 지금이 작업을한지 얼마 안됐다.하지만 이걸 내가 사용했던 것 같아. https://github.com/Wolfy87/EventEmitter – NilsH

관련 문제