Плагин jQuery templates: как создать двустороннюю привязку? - PullRequest
2 голосов
/ 23 февраля 2011

Я начал использовать плагин шаблонов jQuery (созданный Microsoft), но теперь я сталкиваюсь с этой проблемой: шаблон предназначен для набора форм, связанных с массивом объектов;когда я что-то изменяю в одной из форм, я хочу обновить связанный объект и не могу понять, как это автоматизировать.

Вот простой пример (реальные шаблон и объект намного сложнее):

<!-- Template -->
<script type="text/html" id="tmplTest">
    <input type="text" value="${textvalue}"/>
</script>

<!-- object to bind -->
<script type="text/javascript">
    var obj = [{textvalue : "text1"},{textvalue : "text2"}]

    jQuery("#tmplTest").tmpl(obj)
</script>

Это заполнит два текстовых поля, каждое из которых связано со значением из соответствующего объекта.Теперь, если я изменю значение в одном из текстовых полей, мне нужно обновить значение соответствующего объекта данных.Есть идеи, как это сделать?

Ответы [ 2 ]

9 голосов
/ 24 февраля 2011

Шаблон jQuery на самом деле не реализует двустороннее связывание данных, но другой плагин, разработанный Microsoft, делает это.Это сообщение Скотта Гатри фактически охватывает как плагин tmpl, так и плагин Data Linking.Прокрутите вниз до «Поддержка связывания данных клиента», где Скотт подробно расскажет о том, как работает плагин связывания данных.

Однако для двухстороннего связывания данных я нахожу расширение knockoutjs быть намного лучше и чище.Декларативный синтаксис обеспечивает чистоту разметки, а пользовательские переопределения привязки данных допускают множество приложений.Наконец, подключаемый модуль mapping отлично подходит для обработки JSON с сервера в привязку.Наконец, у knockoutjs также есть привязки на основе плагина tmpl .

Удачи в вашей проблеме.

РЕДАКТИРОВАТЬ: обновленный пример кода

Требуются скрипы:

<script src="/Scripts/jquery-1.5.0.min.js" type="text/javascript"></script>    
<script src="/Scripts/jquery.tmpl.js" type="text/javascript"></script> 
<script src="/Scripts/knockout.js" type="text/javascript"></script>      
<script src="/Scripts/knockout.mapping.js" type="text/javascript"></script>    

Тогда вот мясо и картофель

<!-- div for loading the template -->
<div data-bind='template: { name: "tmplTest", foreach: viewModel.list }'>    
</div>

<!-- your template -->
<script type='text/html' id='tmplTest'>
    <div>        
        <span data-bind='text: textvalue, uniqueName: true'></span>
        <input data-bind='value: textvalue, uniqueName: true, valueUpdate:"afterkeydown"'/>
    </div>
</script>

<script type='text/javascript'>
       var viewModel = ko.mapping.fromJS(
        {            
            list:[  { textvalue: "text1" },
                    { textvalue: "text2"}   ]
                }); 

        $(function() {
            ko.applyBindings(viewModel);
        });
 </script>
0 голосов
/ 23 февраля 2011

Вы можете написать собственную ссылку на данные. Примечание : мне нужен индекс для этой работы, поэтому я добавил ваши данные в массив и поместил каждый из них в шаблон. Если кто-то знает, как получить индекс без использования каждого из них, добавьте :) jsfiddle link

<script type="text/html" id="tmplTest">
    {{each inputs}}
    <input type="text" class="datalink" data-key="textvalue" data-index="${$index}" value="${$value.textvalue}"/>
    {{/each}}
</script>
<div id="output"></div>


$.extend(window, {
    data:[
        {inputs: [{textvalue:"text1"},{textvalue:"text2"}]}
    ]
});

$('#output').append($("#tmplTest").tmpl(window.data));

$('#output .datalink').live('change', function(){ // update object on change
    var $this = $(this),
        d = $this.data();
    window.data[0].inputs[d.index*1][d.key] = $this.val();
    console.log(window.data[0].inputs);
});
...