用可观察的孩子观察到的摧毁?

时间:2015-11-24 20:15:16

标签: javascript knockout.js

我解释一下这个问题有点复杂。 基本上我有一个viewmodel,我绑定到一个视图,在该viewmodel中我有一个可观察的对象,我绑定到视图与来自knockout的“with”标签。 此属性称为SelectedItem,因为它表示您从网格中选择的项目。此网格中的数据是普通对象,因此我必须转换为obervable对象,以便将其绑定到此视图。

当我必须绑定第二个对象时,问题就出现了,应用程序就不起作用了。

我为这个问题创造了一个小提琴。 http://jsfiddle.net/q7q0f7oq/11/

Natal.applyBindings(myViewModel).done(function() {
    Natal.Validation.init('#editForm');
});

这是我在工作中使用的库,它封装了Knockoutjs和其他库。

如果你按下新按钮,然后按下保存按钮(没有完成任何操作),它将触发验证。然后用取消按钮关闭窗口,再次打开窗口,再次按下新按钮。 当您尝试再次执行验证时,它将失败。

现在,我发现这不是与Knockout进行此绑定的正确方法,但我不知道我该怎么做才能解决这个问题。 唯一能解决这个问题的方法就是回收对象,不要创建新对象。

1 个答案:

答案 0 :(得分:1)

看起来你不熟悉Knockout的工作方式。你不能以你的方式混合jQuery和Knockout并获得好的结果。 Knockout方法是您从viewmodel控制视图。你不能直接到达并直接摆弄DOM。如果您觉得必须摆弄DOM,请问自己"为什么我不通过模型这样做?"

Natal的验证看起来对Knockout不友好,因为它显然想直接在DOM上工作。你无能为力。

我找到了一个用于Bootstrap模式的bindingHandler供你使用,所以它现在由modalIsOpen可观察的控制。我创建了observable来绑定其他表单输入。我将验证和重置函数放在viewmodel中,而不是让它们是全局的。我使用绑定来挂钩点击事件。

每次重置表单时,为codigo创建一个新的observable似乎没有意义;相反,我只是改变了它的价值。也许这有所不同。我不知道。现在运行验证没有问题。



ko.bindingHandlers.modal = {
  init: function(element, valueAccessor) {
    $(element).modal({
      show: false
    });

    var value = valueAccessor();
    if (ko.isObservable(value)) {
      $(element).on('hide.bs.modal', function() {
        value(false);
      });
    }
    ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
      $(element).modal("destroy");
    });

  },
  update: function(element, valueAccessor) {
    var value = valueAccessor();
    if (ko.utils.unwrapObservable(value)) {
      $(element).modal('show');
    } else {
      $(element).modal('hide');
    }
  }
};

$(document).ready(function() {

  // Cuando se oculta el modal, reseteo la validación para que cuando vuelva a abrir no esten las marcas de validación

  // Definimos el viewmodel del ejemplo
  var ViewModel = function() {
    var self = this;
    var form = "#editForm";

    function resetForm() {
      Natal.Validation.reset(form);
      var item = self.selectedItem();
      item.codigo(0);
      item.descripcion('');
      item.comments('');
    }

    self.modalIsOpen = ko.observable(false);
    self.openModal = function() {
      self.modalIsOpen(true);
    };
    self.closeModal = function() {
      self.modalIsOpen(false);
      resetForm();
    };

    self.validar = function(data, event) {
      if (Natal.Validation.validate(form)) {
        console.log('validacion true');
      } else {
        console.log('validacion false');
      }
    };

    self.selectedItem = Natal.observable({
      codigo: Natal.observable(12345),
      descripcion: Natal.observable('Whatever'),
      comments: Natal.observable('')
    });
  };

  var myViewModel = new ViewModel();

  Natal.applyBindings(myViewModel).done(function() {
    Natal.Validation.init('#editForm');
  });

});

<script src="https://natalfwk.gruposancorseguros.com/1.4.6/natal.min.js"></script>
<link href="https://natalfwk.gruposancorseguros.com/1.4.6/natal.min.css" rel="stylesheet" />
<div id="myToolbar">
  <button class="btn btn-primary" data-toggle="modal" data-bind="click:openModal">New</button>
</div>
<div id="modalNuevo" data-bind="modal:modalIsOpen" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-scrollable">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span>

        </button>
        <h4 class="modal-title">Generic Title</h4>

      </div>
      <div class="modal-body">
        <form id="editForm" class="">
          <div class="form-body" data-bind="with: selectedItem">
            <div class="row">
              <div class="form-group col-md-3">
                <label for="inCodigo" class="control-label">Code</label>
                <input type="text" class="form-control" id="inCodigo" name="inCodigo" data-bv-notempty="true" data-inputmask="'alias': 'integer'" data-bind="value: codigo" />
              </div>
            </div>
            <div class="row">
              <div class="form-group col-md-6">
                <label for="inDescripcion" class="control-label">Description</label>
                <input type="text" class="form-control" id="inDescripcion" name="inDescripcion" data-bv-notempty="true" data-bind="value: descripcion" />
              </div>
            </div>
            <div class="row">
              <div class="form-group col-md-6">
                <label for="description" class="control-label">Comments</label>
                <textarea class="form-control" cols="20" id="textArea" rows="3"></textarea>
              </div>
            </div>
          </div>
        </form>
      </div>
      <div class="modal-footer">
        <button nf-btn-guardar-registro type="button" class="btn btn-primary" data-bind="click:validar">Save</button>
        <button nf-btn-cancelar-modal type="button" class="btn btn-link" data-bind="click: closeModal">Cancel</button>
      </div>
    </div>
  </div>
</div>
&#13;
&#13;
&#13;