2015-02-24 3 views
0

Я создал расширитель нокаута, поэтому я могу легко вернуть поля формы к их исходным значениям.Перемещение логики с точки зрения на пользовательскую привязку

Я хочу, чтобы вырезать загромождали с моей точки зрения, поэтому я хочу, чтобы превратить это:

<div data-bind="if: myObservedValue.hasChanges"> 
    <a href="#" data-bind="click: myObservedValue.revert">Revert</a> 
</div> 

В чем-то вроде этого:

<a href="#" data-bind="revert: myObservedValue">Revert</a> 

Я знаю, что мне нужно, чтобы создать пользовательскую привязку но я изо всех сил стараюсь найти чистый способ:

  1. Только передайте мою наблюдаемую привязку и примените видимую привязку rnally (с учетом того, или нет, мое наблюдаемого расширений hasChanges)
  2. Объединения нескольких привязок с момента моего «Возвратить» связывания нужно будет использовать «нажмите» и «видимые» привязки
  3. Избегайте воздействия на функцию вернуться к моим

заранее спасибо

ko.extenders.revert = function(target, option) { 
 
    target.revert = function() { 
 
    target(target.previousValue); 
 
    target.hasChanges(false); 
 
    }; 
 

 
    target.previousValue = option; 
 
    target.hasChanges = ko.observable(false); 
 
    target.hasChanges.extend({ 
 
    rateLimit: 100 
 
    }); 
 
    target.subscribe(function(newValue) { 
 
    target.hasChanges(target() != target.previousValue); 
 
    }); 
 
    return target; 
 
}; 
 

 
var Vm = function(initialValue) { 
 
    this.myObservedValue = ko.observable(initialValue).extend({ 
 
    revert: initialValue 
 
    }); 
 
    this.revert = function() { 
 
    this.revert(); 
 
    }.bind(this.myObservedValue); 
 

 
    return { 
 
    myObservedValue: this.myObservedValue, 
 
    revert: this.revert 
 
    } 
 

 
} 
 

 
ko.applyBindings(new Vm('Edit me!!!'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<input data-bind="textInput: myObservedValue" /> 
 
<div data-bind="if: myObservedValue.hasChanges"> 
 
    <a href="#" data-bind="click: myObservedValue.revert">Revert</a> 
 
</div>

ответ

0

Вы можете использовать applyBindingsToNode функции, чтобы обернуть другие привязки

ko.extenders.revert = function(target, option) { 
 
    target.revert = function() { 
 
    target(target.previousValue); 
 
    target.hasChanges(false); 
 
    }; 
 

 
    target.previousValue = option; 
 
    target.hasChanges = ko.observable(false); 
 
    target.hasChanges.extend({ 
 
    rateLimit: 100 
 
    }); 
 
    target.subscribe(function(newValue) { 
 
    target.hasChanges(target() != target.previousValue); 
 
    }); 
 
    return target; 
 
}; 
 

 
var Vm = function(initialValue) { 
 
    this.myObservedValue = ko.observable(initialValue).extend({ 
 
    revert: initialValue 
 
    }); 
 
    this.revert = function() { 
 
    this.revert(); 
 
    }.bind(this.myObservedValue); 
 

 
    return { 
 
    myObservedValue: this.myObservedValue, 
 
    revert: this.revert 
 
    } 
 

 
} 
 

 
ko.bindingHandlers["revert"] = { 
 
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
 
    var obs = valueAccessor(); 
 
    
 
    ko.applyBindingsToNode(element, { visible: obs.hasChanges, click: obs.revert }); 
 
    }, 
 
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
 
    } 
 
} 
 

 
ko.applyBindings(new Vm('Edit me!!!'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<input data-bind="textInput: myObservedValue" /> 
 
<a href="#" data-bind="revert: myObservedValue">Revert</a>

можно избавиться от якоря все вместе, окружив привязки TextInput, а

var oldTextInputInit = ko.bindingHandlers["textInput"].init; 
 

 
ko.bindingHandlers["textInput"].init = function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
 
    
 
    var obs = valueAccessor(); 
 

 
    if (obs.revert && obs.hasChanges) { 
 
    var a = element.ownerDocument.createElement('a'); 
 
    a.href = '#'; 
 

 
    if (element.nextSibling) { 
 
     element.parentNode.insertBefore(a, element.nextSibling); 
 
    } else { 
 
     element.parentNode.appendChild(a); 
 
    } 
 

 
    ko.applyBindingsToNode(a, { text: 'Revert', visible: obs.hasChanges, click: obs.revert }); 
 
    } 
 
    return oldTextInputInit(element, valueAccessor, allBindings, viewModel, bindingContext); 
 
}

Вы также можете добавить еще одну пользовательскую привязку к t он вводится, который считывается переопределенной привязкой textInput, поэтому вы можете передать имя шаблона для управления добавочным HTML для добавления и т. д.

+0

Спасибо, Роберт. Я также нашел видео от Ryan Niemeyer о механизме предварительной обработки, который, по-видимому, может упростить синтаксис: https://www.youtube.com/watch?v=kep19WW7rp8#t=326 –

Смежные вопросы