现在如何使用Blaze在Meteor模板中的动态字段上使用X-editable?

yan*_*tel 4 meteor x-editable meteor-blaze

我在Meteor 0.7.2中进行了x-editable工作,但是由于升级到0.8.0,它不再正确呈现.我倾向于最终得到一堆空标签.这是令人沮丧的,因为数据就在那里,而不是在渲染函数被触发时.

<template name="clientPage">
    <header>{{> clientPageTitleUpdate}}</header>
</template>

<template name="clientPageTitleUpdate">
    <h1><span class="title-update editable" data-type="text" data-pk="{{_id}}" data-name="title" data-value="{{title}}">{{title}}</span></h1>
</template>


    Template.clientPageTitleUpdate.rendered = function() {

        console.log(this.$(".title-update").text());

        // set up inline as defaule for x-editable
        $.fn.editable.defaults.mode = 'inline';

        $(".title-update.editable:not(.editable-click)").editable('destroy').editable({

            url:    "empty",
            toggle: "dblclick",

            success: function (response, newValue) {
                // update value in db
                var currentClientId = $(this).data("pk");
                var clientProperties = { title: newValue };

                Clients.update(currentClientId, {$set: clientProperties}, function(error) {
                    if (error) {
                        Errors.throw(error.message)
                    }
                });
            }// success

        });

    }
Run Code Online (Sandbox Code Playgroud)

我曾尝试embeding到另一个模板以此作为解释的"新"的渲染方法在这里,它似乎并没有任何工作.

现在使用x-editable的最佳方法是什么,渲染只会触发一次并且不能确保数据存在.

我正在使用Iron Router,我的模板没有嵌入{{#each}}块中,这似乎是新渲染模型的基本解决方案.

这个问题与这个关于流星模板中x-editable的旧主题有关.

任何帮助都会在这里得到超级赞赏.我很茫然.谢谢

And*_*Mao 8

编辑:现在在Meteor 0.8.3中更容易实现:

模板:

<template name="docTitle">
    <span class="editable" title="Rename this document" data-autotext="never">{{this}}</span>
</template>
Run Code Online (Sandbox Code Playgroud)

码:

Template.docTitle.rendered = ->
  tmplInst = this

  this.autorun ->
    # Trigger this whenever data source changes
    Blaze.getCurrentData()

    # Destroy old editable if it exists
    tmplInst.$(".editable").editable("destroy").editable
      display: ->
      success: (response, newValue) -> # do stuff
Run Code Online (Sandbox Code Playgroud)

为了最有效,请确保可编辑模板的数据上下文仅是正在编辑的字段,如上面的示例所示{{> docTitle someHelper}}.


Meteor 0.8.0至0.8.2的过时信息如下

我也必须这样做,但不确定在我的应用程序中使用全局帮助程序.所以我试图通过改变可编辑的行为来实现它.

仔细阅读文档和资源后,需要完成的主要工作包括:

这是代码(为Coffeescript道歉):

Template.foo.rendered = ->
  container = @$('div.editable')
  settings =
    # When opening the popover, get the value from text
    value: -> $.trim container.text()
    # Don't set innerText ourselves, let Meteor update to preserve reactivity
    display: ->
    success: (response, newValue) =>
      FooCollection.update @data._id,
        $set: { field: newValue }
      # Reconstruct the editable so it shows the correct form value next time
      container.editable('destroy').editable(settings)
  container.editable(settings)
Run Code Online (Sandbox Code Playgroud)

这很难看,因为它在设置新值后销毁并重新创建弹出框,以便表单字段从正确的值更新.

经过一些更多的逆向工程后,我发现了一种更简洁的方法,不会破坏可编辑的方法.加迪是正确的,这container.data().editableContainer.formOptions.value与它有关.这是因为此值是在更新后设置的,因为x-editable认为它现在可以缓存它.好吧,它不能,所以我们用原始函数替换它,因此值继续从文本字段更新.

Template.tsAdminBatchEditDesc.rendered = ->
  container = @$('div.editable')
  grabValue = -> $.trim container.text() # Always get reactively updated value
  container.editable
    value: grabValue
    display: -> # Never set text; have Meteor update to preserve reactivity
    success: (response, newValue) =>
      Batches.update @data._id,
        $set: { desc: newValue }
      # Thinks it knows the value, but it actually doesn't - grab a fresh value each time
      Meteor.defer -> container.data('editableContainer').formOptions.value = grabValue
Run Code Online (Sandbox Code Playgroud)

笔记:

我将尝试在未来更加简洁,等待Meteor更好地支持依赖于数据的反应性.


gad*_*icc 5

针对Meteor 0.8.3+更新

这涵盖了我的所有案例(见下面的代码).这使用非常精细的反应性,并且仅在指定的值更改时才更新x-editable实例.

模板:

<!-- once off for your entire project -->
<template name="xedit">
    {{> UI.contentBlock}}
</template>

<!-- per instance -->
<template name="userInfo">
  {{#xedit value=profile.name}}<a>{{profile.name}}</a>{{/xedit}}
</template>
Run Code Online (Sandbox Code Playgroud)

客户端Javascript(适用于Meteor 0.8.3+):

// once off for your entire project
Template.xedit.rendered = function() {
  var container = this.$('*').eq(0);
  this.autorun(function() {
    var value = Blaze.getCurrentData().value;
    var elData = container.data();
    if (elData && elData.editable) {
      elData.editable.setValue(value, true);
      // no idea why this is necessary; xeditable bug?
      if (elData.editableContainer)
        elData.editableContainer.formOptions.value = elData.editable.value;
    }
  });
}

// per instance; change selector as necessary
Template.userInfo.rendered = function() {
  // Note you don't need all the :not(.editable) stuff in Blaze
  this.$('a').editable({
    success: function(response, newValue) {
      // according to your needs
      var docId = $(this).closest('[data-user-id]').attr('data-user-id');
      var query = { $set: {} }; query['$set']['profile.username'] = newValue;
      Meteor.users.update(docId, query);
    }
  });
});
Run Code Online (Sandbox Code Playgroud)

您可以在http://doingthiswithmeteor.com/(打开两个窗口)中查看它.您需要登录,但请尝试更改"我"页面上的任何信息.

  1. 像往常一样在render()中设置x-editable
  2. 能够自定义显示功能,"空"值等.
  3. 打开两个窗口.更改win1中的值,单击win2中的值..POPUP应显示正确的值.
  4. 支持自定义帮助程序中的日期和数组等自定义类型

刚刚实施了这个...仍在做一些测试,但欢迎反馈.这取代了我以前的帮助程序.