代码之家  ›  专栏  ›  技术社区  ›  Brian Postow

从javascript生成的HTML按钮调用javascript

  •  0
  • Brian Postow  · 技术社区  · 6 年前

    我有一个Ruby on Rails项目(可能不相关),它有一个由java/coffescript生成的表。

    我已经看过了 Using an HTML button to call a JavaScript function doFunction “功能。。。

    目前,我有:

    class App.Table extends Backbone.Model
      defaults: {
        showPastResults: true
      }
    
      initialize: ->
        @set("selectedCohortLabel", @get("cohortLabels")[0])
    
      headers: =>
       [BLAH BLAH BLAH]
    
      columns: =>
        columns = []
    
        [BLAH BLAH BLAH]
        Array::push.apply columns, [['<input id="clickMe" type="button" value="clickme" onclick="doFunction();" />', 5, 5]]    if @get('haveDataBytes')
        columns
    
      doFunction: ->
        console.log("foo")
    

    多芬

    420450:1 Uncaught ReferenceError: doFunction is not defined
        at HTMLInputElement.onclick (420450:1)
    onclick @ 420450:1
    

    doFunction应该住在哪里,以便在运行时找到它?

    1 回复  |  直到 6 年前
        1
  •  0
  •   chriopp    6 年前

    您的方法并没有真正遵循主干架构。你的脊梁骨 将业务域建模为模型和模型集合。如果你跟着

    给你的模特取名的决定 Table 在这个上下文中是错误的,因为表是 有代表性的物体。数据本身可以以多种方式显示。

    一种对Backbone.js不起作用的方法。数据被建模为一个集合 请按照源代码中的注释进行进一步解释。

    显示在这里。确保提供必要的依赖项)。

    <!doctype html>
    <html>
        <head>
            <title>Coffeescript And Backbone</title>
            <link rel="stylesheet" href="style.css">
        </head>
        <body>
            <div class="container">
                <h2>Elements Table</h2>
                <div class="table"></div>
            </div>
    
            <script id="tablerow" type="text/x-handlebars-template">
                <td>{{id}}</td>
                <td>{{name}}</td>
                <td>{{value}}</td>
                <td><button class="button">HaveDataBytes</button></td>
            </script>
    
            <script src="app.js"></script>
        </body>
    </html>
    

    文件:app.coffee

    # The template is integrated in index.html (script#tablerow).
    # Here I read and compile the template function for the table row.
    #
    # This must be called after the template script is in the DOM.
    #
    # Using a packaging tool like browserify or webpack would allow you
    # to precompile the templates during the packaging process, but this
    # approach is good for small applications.
    compileTemplate = (name) ->
        source = document.getElementById(name).innerHTML
        Handlebars.compile(source)
    
    rowTemplate = compileTemplate('tablerow')
    
    # Define the applications backbone
    App =
        View: {}
        Model: {}
        Collection: {}
    
    # This is a dummy dataset of elements that would be fetched from the server
    # using the Collection abstraction. Each entry in data will be represented
    # in a table view further down.
    data = [
        { id: 1, name: "element1", value: "value1", haveDataBytes: true },
        { id: 2, name: "element2", value: "value2", haveDataBytes: false },
        { id: 3, name: "element3", value: "value3", haveDataBytes: true },
        { id: 4, name: "element4", value: "value4", haveDataBytes: true },
        { id: 5, name: "element5", value: "value5", haveDataBytes: false }
    ]
    
    # The model element takes up each entry from data ...
    class App.Model.Element extends Backbone.Model
    
    # and is stored in a collection of Element models
    class App.Collection.Elements extends Backbone.Collection
        model: App.Model.Element
    

    主要的好处是所有的数据都由主干网保存和控制。 将单个条目序列化到服务器,响应单个条目的更改-

    # The table view
    class App.View.ElementsTable extends Backbone.View
    
        # is a table by itself
        tagName: 'table'
    
        # it receives the collection of elements
        initialize: (options) ->
            @collection = options.collection
    
        # and renders each row ...
        render: ->
            @collection.each(@renderRow, @)
            @
        # ... in a element table row view
        renderRow: (row) ->
            rowView = new App.View.ElementTableRow(model: row)
            @$el.append(rowView.render().el)
    
    #  The element table row ...
    class App.View.ElementTableRow extends Backbone.View
        # ... is itself a row
        tagName: 'tr'
    
        # and takes an element model
        initialize: (options) ->
            @model = options.model
    
        # it handles the click event ...
        events: {
            'click button': 'click'
        }
    
        # ... with full access to the model and the collection, which is a member
        # of the element model
        click: (evt) ->
            console.log(evt.target.name, @model, @model.collection)
            @$('td').toggleClass('red')
    
        # render uses the precompiled handlebars template to render the row,
        # no HTML in the view or the model necessary
    
        render: () ->
            @$el.html(rowTemplate(this.model.toJSON()))
            # Here I show/hide the buttons based on the element models data.
            # It would definitely be better to not render the buttons in first place
            if not @model.get('haveDataBytes')
                @$('button').hide()
            @
    
    
    # simple start script
    $(() ->
        # 'load' the data as a collection
        collection = new App.Collection.Elements(data)
    
        # check the elements
        console.log(collection.models)
    
        # create and render the table view
        view = new App.View.ElementsTable(collection: collection)
        $('.table').append(view.render().el)
    )
    

    最后但并非最不重要, doFunction 应该生活在视野中(请参见 click App.View.ElementTableRow )或由的单击处理程序调用 App.View.element表格行