在自定义绑定中Knockout ObservableArray

时间:2018-06-02 09:59:19

标签: javascript knockout.js

我可以在自定义绑定中的init块中创建observableArray吗? 另外,我想在此更新方法中使用此observableArray来推送一些新元素。

它循环 例如:

    ko.bindingHandlers.yourBindingName = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var animateImageArray = ko.observableArray(["img1", "img2"]);
        ko.applyBindings(animateImageArray);
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        //Also can I get a reference to animateImageArray here
    }
};

HTML

    <div class="customized-slider-wrapper" data-bind="yourBindingName: someData">
    <div class="customized-slider" data-bind="foreach: animateImageArray">
    <div class="individual-tile">
        <img data-bind= "attr: {src: $data}" />
    </div>
    </div>
</div>

编辑:

在评论中尝试以下代码

      StopAnimation = setInterval(function () {

        _index++;
        if (_index >= imgArray.length) {
          _index = 0;
        }


         $(temp[_index]).attr('src', imgArray[_index]);


        toBeScrolledBy = slideWidth * _index;
        $(scroller).css({
          'transform': 'translateX(-' + toBeScrolledBy + 'px)'
        });

      }, 1500);

现在图像动画的序列出错了。 第一个图像滑动和第二个加载,动画返回到第一个而不是第三个,并且每次在图像src数组中传递新索引时都会发生。

1 个答案:

答案 0 :(得分:3)

根据您的描述,init不应该创建数组,并且数组可能不必是可观察的。相反,您的可观察产品数组将包含对象,并且每个产品对象将具有其图像的数组(可能不必是可观察的)。粗略草图:

&#13;
&#13;
var vm = {
  products: ko.observableArray([
      {
          name: "Widget",
          images: [
              "https://via.placeholder.com/100/5d5/fff.png?text=Widget+1",
              "https://via.placeholder.com/100/d55/fff.png?text=Widget+2",
              "https://via.placeholder.com/100/55d/fff.png?text=Widget+3"
          ]
      },
      {
          name: "Gadget",
          images: [
              "https://via.placeholder.com/100/55d/fff.png?text=Gadget+1",
              "https://via.placeholder.com/100/5d5/fff.png?text=Gadget+2",
              "https://via.placeholder.com/100/d55/fff.png?text=Gadget+3",
              "https://via.placeholder.com/100/55d/fff.png?text=Gadget+4",
              "https://via.placeholder.com/100/5d5/fff.png?text=Gadget+5"
          ]
      },
  ])
};

ko.bindingHandlers.productSlides = {
    init: function(element, valueAccessor) {
      // Current timer handle
      var timer = 0;
      // Current slide index
      var index = 0;

      // Show first slide
      element.src = ko.unwrap(valueAccessor())[index];

      // Set up handlers
      element.addEventListener("mouseenter", startTimer);
      element.addEventListener("mouseleave", clearTimer);
  
      // Show next slide
      function nextSlide() {
          // Re-read the observable in case it's changed
          var slides = ko.unwrap(valueAccessor());
          index = (index + 1) % slides.length;
          element.src = slides[index];
      }
  
      // Start showing slides
      function startTimer() {
        if (!timer) {
            nextSlide();
            timer = setInterval(nextSlide, 1000);
        }
      }
      
      // Stop showing slides
      function clearTimer() {
          if (timer) {
              clearInterval(timer);
              timer = 0;
          }
      }
      
      // Clean up on disposal
      ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
          element.removeEventListener("mouseenter", startTimer);
          element.removeEventListener("mouseleave", clearTimer);
          clearTimer();
      });
    }
};

console.log("Showing products");
ko.applyBindings(vm, document.body);

// Example of adding another product to the array later
setTimeout(function() {
    console.log("Adding third product");
    vm.products.push({
        name: "Doogle",
        images: [
            "https://via.placeholder.com/100/d55/fff.png?text=Doogle+1",
            "https://via.placeholder.com/100/5d5/fff.png?text=Doogle+2",
            "https://via.placeholder.com/100/55d/fff.png?text=Doogle+3",
            "https://via.placeholder.com/100/d55/fff.png?text=Doogle+4"
        ]
    });
}, 2000);
&#13;
<div data-bind="foreach: products">
  <img data-bind="productSlides: images">
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
&#13;
&#13;
&#13;