2011-08-24 4 views
2

저는 KnockoutJs에 매우 익숙합니다. 그래서 나는 이런 종류의 상황에 대해 잘 알려지지 않은 모범 사례가 있다는 것을 기대하고 있습니다.글로벌 viewModel없이 클릭 핸들러를 knockoutjs의 템플릿에 바인딩하는 방법은 무엇입니까?

항목 배열이 포함 된보기 모델이 있습니다. 템플릿을 사용하여 이러한 항목을 표시하려고합니다. 또한 각 항목에보기 모드와 편집 모드를 전환 할 수 있기를 바랍니다. Knockout에 가장 잘 맞는 것은 배열의 각 항목에 대한 기본 뷰 모델 또는 (아마도 더 나은) 관련 함수를 만든 다음이 함수를 템플릿에 바인딩하는 것입니다. 그래서 난 내 페이지에이 코드를 만들었습니다

<ul data-bind="template: {name: testTemplate, foreach: items}"></ul> 

<script id="testTemplate" type="text/x-jquery-tmpl"> 
    <li> 
    <img src="icon.png" data-bind="click: displayEditView" /> 
    <span data-bind="text: GBPAmount"></span> 
    <input type="text" data-bind="value: GBPAmount" /> 
    </li> 
</script> 

<script> 
(function() { 
    var viewModel = new TestViewModel(myItems); 
    ko.applyBindings(viewModel); 
})(); 
</script> 

그리고이 별도의 파일 :

function TestViewModel(itemsJson) { 

    this.items = ko.mapping.fromJS(itemsJson); 

    for(i = 0; i < this.items.length; ++i) { 
    this.items[i].displayEditView = function() { 
     alert("payment function called"); 
    } 
    } 

    this.displayEditView = function() { 
    alert("viewmodel function called"); 
    } 
}; 

때문에 내 JS 글로벌 네임 스페이스에 아무것도를 추가 할 수 없습니다 I에서 실행되는 환경에 따라서보기 모델을 만들고 설정하는 익명 함수. (필요한 경우 추가 할 수있는 네임 스페이스가 있습니다.)이 제한 사항은 글로벌 viewModel 변수에 의존하는 것으로 보이는 모든 예제를 손상시키는 것으로 보입니다.

P. 만약 내가하려고하는 것보다 knockoutJS에 더 잘 맞는 접근법이 있다면 그것을 제안 해주십시오!

답변

9

viewModel에 전역으로 액세스 할 수없는 경우 몇 가지 옵션이 있습니다.

먼저 템플릿 바인딩에 templateOptions 매개 변수를 사용하여 관련 방법을 전달할 수 있습니다.

그것은 (또한 정적 템플릿 이름은 따옴표에 있어야 있습니다)과 같습니다

data-bind="template: {name: 'testTemplate', foreach: items, templateOptions: { vmMethod: methodFromMainViewModel } }" 

그런 다음, 템플릿의 내부 vmMethod$item.vmMethod으로 제공 될 것이다. 마지막 매개 변수로 templateOptions를 사용하는 경우에는 중괄호 사이에 공백이 있는지 확인하십시오 { { 또는 jQuery 템플릿은 자체 파싱을 시도합니다.

그래서, 당신처럼 결합 할 수 있습니다

<img src="icon.png" data-bind="click: $item.vmMethod" /> 

다른 옵션은 방법 및 각 항목에 뷰 모델에서 관련 아무것도에 대한 참조를 넣어하는 것입니다. 당신이 그 옵션을 탐색하고있는 것처럼 보입니다.

:

마지막 KO 1.3 (잘하면 9 월에서 곧 베타) jQuery의 라이브/대리인 기능 같은 것을 사용하고 (http://jsfiddle.net/rniemeyer/5wAYY/이 샘플에서처럼) 당신의 ViewModel로를 연결하는 좋은 방법이 될 것입니다

또한 post의 "이벤트 바인딩에서 익명 함수 방지"섹션도 도움이 될 수 있습니다. 동적으로 선택한 템플릿을 사용하여 편집 샘플을 찾고 있다면이 post이 도움이 될 수 있습니다.

+0

감사합니다. 매우 도움이됩니다. – Dan

0

변수 methods (기능)을 녹아웃 템플릿으로 전달하는 방법을 묻는 분들을위한 것입니다. Templating의 핵심 기능 중 하나는 가변 데이터를 사용하는 것이며 String 또는 function 일 수 있습니다. KO에서 이러한 변수는 템플릿을 렌더링 할 data 또는 foreach 속성에 포함될 수 있습니다.data 또는 foreach에 포함 된 개체는 String, function 등이 $data을 사용하여이 컨텍스트에서 액세스 할 수 있습니다.

이 코드를보고 기능을 녹아웃 템플릿에 전달하는 데 도움이되는지 확인할 수 있습니다. 여러 템플릿을 제공하려면

function ViewModel() { 
this.employees = [ 
    { fullName: 'Franklin Obi', url: 'employee_Franklin_Obi', action: methodOne }, 
    { fullName: 'John Amadi', url: 'employee_John_Amadi', action: methodTwo } 
], 
this.methodOne = function(){ alert('I can see you'); }, 
this.methodTwo = function(){ alert('I can touch you'); } 
} 

ko.applyBindings(new ViewModel()); 


<ul data-bind="template: { name: employeeTemplate, foreach: employees }" ></ul> 
    <script type="text/html" id="employeeTemplate"> 
     <li><a data-bind="attr: { href: '#/'+url }, text: fullName, click: $data.action"></a></li> 
    </script> 

는이처럼 ViewModel에 스위치 방법을 소개하고 각 항목 (직원)에 대한 별칭을 소개 as 속성을 사용하여 구성합니다. 스위치 개체 키 linkable을 항목 개체에 추가해야합니다.

... 
this.employees = [ 
    { fullName: 'Franklin Obi', linkable : false }, 
    { fullName: 'John Amadi', url: 'employee_John_Amadi', action: methodTwo, linkable : true } 
], 
this.methodLinkTemplate = function(employee){return employee.linkable ? "link" : "noLink"; } //this is a two way switch, many way switch is applicable. 
... 

그러면 템플릿 양식의 id은 다음과 같이 명명됩니다.

<ul data-bind="template: { name: employeeTemplate, foreach: employees, as: 'employee' }" ></ul> 
    <script type="text/html" id="noLink"> 
    <li data-bind="text: fullName"></li> 
    </script> 
    <script type="text/html" id="link"> 
    <li><a data-bind="attr: { href: '#/'+url }, text: fullName, click: $data.action"></a></li> 
    </script> 

나는이 코드를 실행하지 않았지만 아이디어가 누군가의 시간을 절약 할 수 있다고 생각합니다.

관련 문제