5

현재 내 백본 + RequireJS 프로젝트에서 Mediator Pattern의 이점을 활용하기 위해 Backbone.Mediator을 사용하고 있습니다. 그러나 필자는 패턴의 독특한 동작에 직면 해 있습니다.이 동작은 "설계 상"이건 아니건간에 Mediator Pattern의 표준 동작이 아니라 플러그인의 버그입니다.백본 + RequireJS + Mediator Pattern 결과 View 논리 단락 및 무한 루프

AMD 모듈 1

var View1 = Backbone.View.extend({ 
    ... 
    events: { 
     'click div: switchList' 
    }, 
    switchList: function() { 
     Backbone.Mediator.pub('list:switch'); 
    } 
}); 

AMD 모듈 2

var View2 = Backbone.View.extend({ 
    ... 
    subscriptions: { 
     'list:switch': 'shrinkDiv' 
    }, 
    shrinkDiv: function() { 
     Backbone.Mediator.pub('div:shrink'); 
     this.shrinkAndMore(); 
    } 
}); 

return View2; 

AMD 모듈 3

,369 : 인위적인 예로서

define(function(require) { 
    var View2 = require(**AMD Module 2**); 

    var View3 = Backbone.View.extend({ 
     ... 
     subscriptions: { 
      'div:shrink': 'createSiblingDiv' 
     }, 
     createSiblingDiv: function() { 
      this.siblingView = new View2(); 
      this.$el.after(this.siblingView.$el); 
      this.siblingView.render(); 
     } 
    }); 
}); 

나는이 같은 일 것이라고 생각 : 생성 한 후 즉시, SiblingDiv : SiblingDiv의 다른 인스턴스가 채널 '스위치 목록'에 가입 뷰 2 때문에

     **View1**.switchList(); 
         │ 
Channel 'list:switch' │ 
         ↓ 
         **View2**.shrinkDiv(); 
         │ 
         ├─┐ 
         │ │ Channel 'div:shrink' 
         │ ↓ 
         │ **View3**.createSiblingDiv(); 
         │ │ 
         │ └──→ "SiblingDiv created and rendered" 
         │ 
         └────→ "View2 Div shrinked and more" 

그러나, 진실은 또한 채널 'list : switch'를 통해 계속 발생하는 이벤트 신호에 의해 트리거됩니다 (이는 **View2**.shrinkAndMore(); 실행 후에 만 ​​중단됩니다).

그래서 실제 코드 흐름은 다음과 같습니다

     **View1**.switchList(); 
         │ 
Channel 'list:switch' │ 
         ↓ 
         **View2**.shrinkDiv(); ←──────────────────┐ 
         │           │ 
         ├─┐          │ 
         │ │ Channel 'div:shrink'     │ 
         │ ↓          │ 
         │ **View3**.createSiblingDiv();   │ 
         │ │          │ 
         │ └──→ "SiblingDiv created and rendered" ─┘ 
         │ 
         └────→ "View2 Div shrinked and more" 

무한 루프 ... 어머!

define(function(require) { 
    var View2 = require(**AMD Module 2**); 

    var View3 = Backbone.View.extend({ 
     ... 
     subscriptions: { 
      'div:shrink': 'createSiblingDiv' 
     }, 
     createSiblingDiv: function() { 
      this.siblingView = new View2({  // new code 
       subscriptions: {}     // new code 
      });         // new code 
      this.$el.after(this.siblingView.$el); 
      this.siblingView.render(); 
     } 
    }); 
}); 

modded하게

var View2 = Backbone.View.extend({ 
    initialize: function() {         // new code 
     if (this.options.subscriptions) {     // new code 
      this.subscriptions = this.options.subscriptions; // new code 
     }             // new code 
    },              // new code 
    ... 
    subscriptions: { 
     'list:switch': 'shrinkDiv' 
    }, 
    shrinkDiv: function() { 
     Backbone.Mediator.pub('div:shrink'); 
     this.shrinkAndMore(); 
    } 
}); 

return View2; 

AMD 모듈 3 modded하게

AMD 모듈 2 :

나는 내 코드에 약간의 수정을 내 방식대로 작업 일을 할 수 있었다 하지만 무한 루프 동작 (새 Object 동안 이벤트 신호 브로드 캐스팅도 매우 신호에 의해 트리거됩니다.)는 중재자 패턴 방법론에서 "표준"으로 간주됩니까? 또는이 모든 플러그인 부분의 버그입니까?

답변

5

플러그인의 버그로 보입니다. 좀 봐봐 this line. 이 채널에 등록 된 모든 이벤트를 반복합니다. 문제는 등록 된 모든 이벤트가 호출되고 모든 루프 단계에서 등록 된 이벤트의 배열 길이를 검사 할 때 중지된다는 것입니다.그래서 무슨 일이 있습니다 :

  1. 등록 된 이벤트가 새로운 인스턴스가 생성됩니다
  2. 호출되는 이벤트를 해고 한
  3. 하여이 증가에게 채널
  4. 에 배열의 길이를 자신을 등록
  5. 그래서 대신 루프를 종료의가 방금 만든 뷰의 리스너를 호출은
  6. 3.
0123로 돌아가

for (var i = 0, l = channels[channel].length; i < l; i++) { 

당신이 처음에 배열의 길이를 얻을이 원인을 해결해야합니다 라인에 변경

. 새로운 요소를 추가하면 무한 루프가 끝나지 않습니다.

+0

좋은 캐치, 그 특성상 버그처럼 보입니다. 이걸 파헤쳐 주셔서 감사하고 위대한 답을 = D – Kay