【问题标题】:Knockout observable with observable child?用可观察的孩子可观察到的淘汰赛?
【发布时间】:2023-03-11 04:15:01
【问题描述】:

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

问题出现在我必须绑定第二个对象时,应用程序无法正常工作。

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

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

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

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

现在,我发现这不是使用 Knockout 进行此绑定的正确方法,但我不知道我能做些什么来解决这个问题。 我唯一想到的就是回收对象,而不是创建新对象。

【问题讨论】:

    标签: javascript knockout.js


    【解决方案1】:

    您似乎不熟悉 Knockout 的工作原理。你不能像以前那样混合使用 jQuery 和 Knockout 并获得好的结果。 Knockout 方式是您从视图模型控制视图。您不会直接接触并摆弄 DOM。如果你觉得你必须摆弄 DOM,问问自己“为什么我不通过模型来做这件事?”

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

    我找到了一个用于 Bootstrap modal 的 bindingHandler 供您使用,所以现在它由 modalIsOpen observable 控制。我制作了 observables 来绑定其他表单输入。我将验证和重置功能放在视图模型中,而不是让它们成为全局的。我使用绑定来连接点击事件。

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

    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>

    【讨论】:

    • 感谢您的时间,问题是我必须这样做,因为它已经完成了,我没有设计它:(。
    • 但是,我会建议你的方法:D
    • 祝你好运。如果您不能以 Knockout 方式做事,我建议您尽可能避免使用 Knockout 功能。
    猜你喜欢
    • 2015-10-05
    • 2014-11-05
    • 2012-09-08
    • 2012-07-07
    • 2015-01-25
    • 1970-01-01
    • 2018-03-30
    • 2012-10-22
    相关资源
    最近更新 更多