代码之家  ›  专栏  ›  技术社区  ›  connexo

淘汰谷歌地图:组件与自定义绑定处理程序

  •  2
  • connexo  · 技术社区  · 8 年前

    当我搜索“ 淘汰谷歌地图 “我发现了很多基于KO的GoogleMaps实现。我能够找到的所有实现都采用了使用自定义绑定处理程序的方法,而我最初打算将其实现为一个Knockout组件。

    示例:

    谁能告诉我正确的方向吗 为什么这里更喜欢自定义绑定处理程序而不是KO组件 ?

    我计划的用例如下:

    我正在实现一个带有地址搜索结果列表的页面。到目前为止,列表是一个KO组件,每个列表条目都是由另一KO组件生成的,列表组件在foreach绑定中重复调用该组件。在这个搜索结果列表旁边,我需要一张谷歌地图,显示地图中的结果条目。列表、列表条目和地图之间也会有很多交互。

    以下是我目前所掌握的:

    var GMap = function () {
        var self = this;
    
        var initMap = function() {
            var map = new google.maps.Map(document.getElementById('map'), {
                zoom: 13,
                center: {lat: 51.4387974, lng: 6.9922915}
            });
        };
      
        initMap();
    };
    $(document).ready(function() {
      ko.components.register('gmap', {
        viewModel: GMap,
        template: { element: 'gmap' }
      });
      ko.applyBindings();
    });
    #map {
      height: 400px;
      width: 600px;
    }
    <script src="https://maps.googleapis.com/maps/api/js?v=3.22"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <gmap></gmap>
    <template id="gmap">
      <div id="map"></div>
    </template>
    2 回复  |  直到 8 年前
        1
  •  6
  •   Community miroxlav    4 年前

    组件和自定义处理程序是完全不同的东西。

    自定义绑定

    基本上是 custom binding 有权访问:

    • 使用它的HTML组件
    • 绑定值(提供给绑定的表达式)
    • 元素中的所有其他绑定
    • 元素的绑定上下文,您可以从中访问 $root , $parent 等等

    其定义包括两个功能:

    • init :允许进行初始设置,如初始化小部件、设置事件处理程序等
    • update :它是在之后调用的 初始化 。此时,您可以通过绑定、所有元素绑定、上下文等访问属性(包括可观察属性)。这将创建订阅,当任何访问的可观察属性更改时,这些订阅将调用update。

    因此,当您需要直接与DOM元素交互时,应该使用自定义绑定,例如修改其属性、初始化小部件、订阅事件等

    组成部分

    组件完全不同。定义组件时,必须定义:

    • 模板,它是一组DOM元素,通常带有绑定
    • 视图模型(通常是构造函数或工厂)

    使用组件时:

    • 视图模型被实例化
    • 模板已加载
    • 视图模型已绑定到模板

    因此,组件允许重用视图模型和模板

    那么,有什么区别?

    自定义绑定可以直接访问DOM元素,允许与它们交互、订阅事件、修改属性等

    组件只是一个视图模型,以及一组绑定到该特定视图模型的DOM元素。

    因此,对于Google Maps,它需要初始化一个小部件(地图)并与map事件交互,并响应可观察的属性请求,您永远不能使用组件,因为组件不允许与DOM元素直接交互。(请记住,是一堆带有绑定的HTML元素,以及相应的视图模型,其中不能包含任何逻辑来插入这些元素)。

    自定义绑定通常应用于单个元素(尽管它可以处理其子元素,如 foreach ). 在谷歌地图的情况下,您只需要显示地图的元素。

    组件通常是一组或多或少复杂的DOM元素,“从外部”是不可访问的。与主视图模型的唯一通信是通过参数完成的。组件不能直接与DOM元素交互:它必须通过ko绑定进行交互。

    因此,对于谷歌地图来说,很明显您需要自定义绑定。

    只有当您想要模块化或重用一组DOM元素和相关的视图模型时,创建一个组件才有意义,它还可以包括访问web服务(通过AJAX)、进行计算(通常通过使用计算的可观测值)等功能。例如,可以使用一个组件来实现购物车,其中包括:

    • 显示购物车中项目的DOM元素(可能是HTML表和一些控件)
    • 用于修改购物车内容的控件(例如,用于删除元素或更改数量)
    • 显示总额、税收等的视图模型
    • 用于存储购物车以备日后使用或付费的功能(可以是对服务的ajax调用)

    在这种情况下,购物车将有一个视图模型,该视图模型将包括计算的可观测值(显示总额和税收)、删除项目、修改数量、存储或支付等功能。还有一组具体的DOM元素,该元素具有此视图模型的绑定,即显示购物车并与其交互的HTML。

    在谷歌地图的情况下,如果没有自定义绑定的帮助,或者没有 黑客使用额外的非ko脚本 .

    如果您想在地图旁边显示一个位置列表,并修改该列表,可以使用一个组件,该组件将包括一个带有列表和相关功能的视图模型,以及一个模板,该模板包含一个带有谷歌地图自定义绑定的元素。这是有意义的:视图模型+几个元素。

    结论

    这意味着定制绑定通常与绑定的DOM元素有深度交互,而组件与元素有更高级别的交互,这必须通过绑定完成。

    因此,他们在一个非常不同的层面上发挥作用。您不能比较或交换它们。

    如果你坚持这样做,你可以创建一个像组件一样的绑定,因为你可以完全控制元素,并且可以完全访问视图模型,但这比组件更难实现。也许也可以用某种深奥的方式反过来。

        2
  •  1
  •   CodingYoshi    4 年前

    结合

    结合 ,一个习惯与否,是一个非常简单的概念,包括两件事:

    1. UI元素的属性发生更改,因此它应该更新对象(ViewModel)
    2. 对象(ViewModel)的属性发生更改,因此它应该更新UI元素。

    从上面来看,如果只实现了1,则称为 单向绑定 (因为如果您更改UI,它将更新对象,但不会反过来)。如果同时实现了1和2,则称为 双向绑定 .

    因此,在任何时候,如果您认为需要做些什么,那么您都需要使用绑定,如果框架没有所需的绑定,则需要使用自定义绑定。

    最有可能的是,你所说的地图需要像上面这样的东西。事实上,这是因为作者在第一段中这样说:

    具体地说,您可以学习如何使地图标记为视图的一部分,并在后面的ViewModel更改时自动更改其位置。

    请看,作者在上面讨论了2个问题:当ViewModel更改时,更改UI元素的位置。

    组成部分

    A. 组成部分 是一个概念,即拥有一个可重用的项目,该项目可能有一个UI,但不一定有,并且所有需要的代码都与它一起打包。这样可以重复使用。例如,它可能只是一个只允许数字的输入UI元素。它所需的所有代码都与UI元素一起打包。

    现在,与它一起打包的代码可能与绑定相关。如果他们使用的框架没有所需的绑定,它甚至可能有自定义绑定。此外,它可能有与绑定无关的附加代码。

    此外,组件可以具有单个UI元素或多个UI元素。具有多个元素的组件的一个很好的例子是消息框。

    结论

    绑定和组件是分开的。组件中可能有绑定,也可能有其他代码使其工作,或者两者兼而有之。

    就您提到的地图而言,它们只添加了一个功能:对ViewModel中的更改做出反应。它不是一个组件,因为它不是自包含和可重用的。

    他们本可以使用一个组件来完成。但是,如果他们这样做并说它是一个KO组件,那么它可能仍然有特定于KO的绑定代码,以及ViewModel和所需的所有UI元素。

    推荐文章