0

我有这个AMD 模块

define(function (require, exports, module) {
'use strict';
var t = require("transducers");
var most = require("most");

var groupby = function (prev, curr) {
       var key = curr.type;
       if (!prev[key]) {
             prev[key] = [curr];
       } else {
            prev[key].push(curr);
       }
       return prev;
};
function category(kv) {
     return {
           type: kv[0],
           label: kv[1][0].label,
           counter: kv[1].length
     }
  }
  function dom(cat) {
       var el = document.createElement("li");
       el.innerHTML = cat.label;
       return el;
  }

function append(prev, curr) {
        prev.appendChild(curr);
        return prev;
 }

function createClick(prev, curr) {
     return prev.merge(most.fromEvent("click", curr)
      .map(function (e) {
            return e.currentTarget.innerHTML;
      })
    )
 }

var xf = t.comp(
                 t.map(category),
                 t.map(dom)
               );

module.exports = {
         main: function (data) {

               var groups = t.reduce(groupby, {}, data);
               var container = t.transduce(xf, append, document.querySelector("ul"), groups);
               var streams = t.reduce(createClick, most.empty(), [].slice.call(container.querySelectorAll("li"), 0));

              streams.forEach(function (e) {
                   console.log("click", e);
               });
        }
     };
});

Main 函数获取项目列表,然后按“类型”属性对它们进行分组。之后,它创建并附加 <li> 元素。最后,它创建了一个点击流。我是反应式编程和转换器的新手。

但我想知道是否有办法创建管道。

我很麻烦,因为 groupby 是一个减少并且不能在转换器中组合它。我确定我错过了一些东西。谢谢

4

1 回答 1

0

尝试将您的问题分解为可以对单个项目和集合进行操作的事物,然后等到最后减少它们。还检查经常错过的“扫描”操作,这可以使您免于过度减少

在您的示例中,您列出了 3 个减少可能的操作: - 将所有点击流合并为一个事件流 - 将所有 dom 合并为一个 ul - 计数

这一切都可以通过扫描来完成,但问题在于您想要唯一的类别,但您还要计算非唯一的类别。从你的例子中不清楚这是否真的是一个要求......

由于大多数已经与传感器类似,因此您并不真正需要它们。对于这个例子,我将坚持使用纯 mostjs;

var most = require("most");

function gel(tag) {
    return document.createElement(tag);
}

var cache = Object.create(null);

function main(dataArray) {
    most.from(dataArray)
//only pass along unique items to represent categories
//optionally, also count...
        .filter(function uniq(item) {
            var category = item.type;
            if (!(category in cache))
                cache[category] = 0;
            cache[category]++;
            return cache[category] == 1;
        })
//transform
        .map(function makeLI(item) {
            var li = gel("li");
            li.innerHTML = item.label;
            item.dom = li;
        })
//attach click handler
        .map(function (item) {
            item.click = most
                .fromEvent("click", item.dom)
                .map(function(e) {
                    item.label;
                });
            return item;
        })
// merge
        .scan(function mergeIn(all, item) {
            el.appendChild(item.dom);
            clicks.merge(item.click);
        }, { ul: gel("ul"), clicks: most.empty() })
//force stream init b creating a demand
        .drain()
//most resolve stream into promises, but we could have just 
//as easily used reduce here instead
        .then(function onComplete(all) {
            all.clicks.forEach(function(msg) {
                console.log("click", e);
            })
        })
}

进一步的变化是可能的。例如,如果我们想为每个类别项目添加一个子列表,我们可以将一个流附加到每个类别的上下文对象,并在我们进行时递增地附加到每个子项

于 2015-09-25T01:46:55.363 回答