3

Я строю приборную панель, используя компоненты мифрила. Панель инструментов состоит из общих компонентов виджета, которые содержат гнездо более специфичные компоненты, такие как виджеты twitter, виджеты продаж и т. Д. Общий виджет является агностиком вложенного компонента.Javascript - Вложенные компоненты мифрила

Теперь у меня есть требование дополнять общий виджет из вложенного компонента. Например, общий виджет имеет панель инструментов с общими операциями с удалением &, я хочу добавить внутренние операции, такие как диапазон дат изменения в случае виджета продажи, изменить учетную запись в случае виджета Twitter.

прямо вперед подход к этому является разлагаются внутренний компонент 2 subcompoents панель инструментов и контента, например, sales_toolbar_component & sales_content_component. Обе эти подкомпонентные сети нуждаются в одних и тех же данных, загружаемых через ajax, следовательно, это приведет к дублированию. Подход должен следовать Гибридная архитектура (http://mithril.js.org/components.html#hybrid-architecture), где компонент верхнего уровня будет выполнять вызовы ajax и передавать данные в конструкторе каждого подкомпонента. Однако в этом случае родительский компонент является общим, не знает о требованиях к данным для детей.

Другой подход заключается в том, чтобы один подкомпонент выполнял вызов ajax и уведомлял о браке по образцу наблюдателя, это, по-видимому, немного внутренняя связь/зависимость

Еще одно соображение заключается в создании компонента, который может иметь несколько представлений & для родителей, чтобы сделать каждый вид в соответствии с требованиями, используя один и тот же контроллер instance.Something как:

//create a component whose controller and view functions receive some arguments 
var component = m.component(MyComponent, {name: "world"}, "this is a test") 

var ctrl = new component.controller() // logs "world", "this is a test" 
m.component(MyComponent.toolbar(ctrl)); 
m.component(MyComponent.content(ctrl)); 

ни один из них не кажется полным, есть шаблон сравнения, который я могу рассмотреть?

ответ

4

Возможно, вам понравился шаблон memoization. Воспоминание включает в себя обертывание функции - в данном случае запроса AJAX - так, чтобы первый вызов с любым заданным входом запускал базовую функцию, но его возвращаемое значение хранится во внутреннем кеше; последующие вызовы с одним и тем же входом извлекают кешированное значение, не касаясь основной функции. Вот простая реализация и memoized функция запроса AJAX, которая оборачивает Mithril-х m.request:

function memoize(fn){ 
    var cache = {} 

    return function memoized(input){ 
    if(!(input in cache)) 
     cache[ input ] = fn(input) 

    return cache[ input ] 
    } 
} 

var get = memoize(function(url){ 
    return m.request({ method : 'GET', url : url }) 
}) 

Таким образом, те компоненты, которые выполняют первый сделают запрос; следующий компонент (который будет выполняться сразу же после этого) получит одно и то же значение.

Что касается идеи создания многопрофильного компонента, это практически не отличается от практического применения вашего первоначального предложения. Рассмотрим следующий код:

var Wrapper = { 
    controller : function(){ 
    // AJAX or whatnot 
    }, 

    view : function(ctrl){ 
    return m('.Wrapper', 
     m(Toolbar, ctrl) 
     m(Content, ctrl) 
    ) 
    } 
} 

m(Wrapper, { name : 'world' }, 'This is a test') 

Здесь я использовал ссылку Wrapper вместо MyComponent и Toolbar и Content лишь компоненты, как первоначально предлагалось. Обертка не является общей, но не была MyComponent. Я нахожу, что пытаясь сократить отдельные единицы кода Мифрила до компонентов, где это возможно, даже если вы предпочитаете иметь меньше компонентов в идеальном мире, обычно делает код намного проще в обслуживании, потому что, в то время как у вас может быть множество контекстно-зависимых модулей вместо нескольких настраиваемых универсальных модулей все эти контекстно-зависимые модули являются общими в том, как они называются, что гораздо более полезно с точки зрения предсказуемости кода.

Сказав это, можно было бы уточнить вашу идею шаблона для передачи одного контроллера нескольким представлениям. Опять же, я хотел бы уменьшить эту модель в компонентную форму, так что мы можем иметь дело с осложнениями внутренне, но разоблачить интерфейс, который соответствует по Митрил:

var MultiView = { 
    controller : function(controller){ 
    return new controller() 
    }, 

    view : function(ctrl){ 
    var views = [].slice.call(arguments, 2) 

    return m('div', 
     view.map(function(view){ 
     return view(ctrl) 
     }) 
    ) 
    } 
} 

m(MultiView, function controller(){ /* AJAX or whatnot */ }, Toolbar.view, Content.view) 

Эта функция запоминания будет работать для любой функции, которая принимает однострочный аргумент, который идеально подходит для запросов AJAX. Если вы хотите получить более полное решение для memoization, ознакомьтесь с funes.

+1

Спасибо @barny, на основе подхода MultiView. Я создал 2 fiddlers https://jsfiddle.net/chifer/f8y1ndwg/1/. Это реализация шаблона, который вы описали, однако он предполагает, что виджет представляет собой компонент вида без контроллера. где https://jsfiddle.net/chifer/rLv1pLg8/ - поддерживает виджетов, чтобы иметь контроллер и ссылается на внутренний контроллер виджетов как на собственность, люблю слышать вашу мысль специально на втором скрипаче. – chifer

+0

Ive принял ответ, надеюсь, что вы получите возможность взглянуть на комментарий jsfiddle.net/chifer/f8y1ndwg/1 & jsfiddle.net/chifer/rLv1pLg8. Было бы неплохо, если рецепты мифрила включают simmilar – chifer

+0

Ha cool. Однако я не понимаю смысла в этих примерах. Почему бы просто не иметь нормальный компонент? https://jsfiddle.net/barney/95t587fb/ – Barney