jQuery Datalink не работает с объектными методами - PullRequest
2 голосов
/ 15 октября 2010

У меня есть объект javascript с несколькими свойствами. Объект также содержит метод экземпляра, который возвращает результат вычисления двух свойств объекта.

Я использую новый плагин Jquery .link () (http://api.jquery.com/link/),) для обновления пользовательского интерфейса и элементов формы со значениями свойств объекта и наоборот, когда обновляется форма или объект.

Это все работает, за исключением одного из элементов формы, который должен содержать результат метода экземпляра объекта, но никогда не обновляется.

Я поместил кнопку в форме, чтобы вручную проверить значение Расхождения, и это работает, но плагин jquery link не заполняет элементы ввода автоматически, хотя он заполняет элементы ввода, связанные со свойствами объекта. Все элементы имеют атрибуты id и name.

Может кто-нибудь сказать мне, где я иду не так?

Мой JavaScript:

<script>

   function Product() {
       this.InStock = 0;
       this.Ordered = 0;

   }

   // object's instance method
   Product.prototype.Discrepancy = ComputeDiscrepancy;

   function ComputeDiscrepancy() {
       return this.InStock - this.Ordered;
   }

   $(document).ready(function () {

       var products = new Array();

       products[0] = new Product();
       products[1] = new Product();

       $("form").link(products[0], {
           InStock: "product0_InStock",
           Ordered: "product0_Ordered",
           Discrepancy: "product0_Discrepancy"
       });

       $("form").link(products[1], {
           InStock: "product1_InStock",
           Ordered: "product1_Ordered",
           Discrepancy: "product1_Discrepancy"
       });
       // button for me to manually check discrepancy method works
       $("#checkData").click(function () {
           alert(products[0].InStock);
           $("#product0_Discrepancy").val(products[0].Discrepancy());
       });

   });   </script>

HTML:

<table>
    <tr>
        <th></th><th>Product 1</th><th>Product 2</th>
    </tr>
    <tr>
        <td> In Stock</td>
        <td><input id="product0_InStock" name="product0_InStock"/></td>
        <td><input id="product1_InStock" name="product1_InStock"/></td>

    </tr>

    <tr>
        <td>Ordered</td>
        <td><input id="product0_Ordered" name="product0_Ordered"/></td>
        <td><input id="product1_Ordered" name="product1_Ordered"/></td>
    </tr>

    <tr>
        <td>Discrepancy</td>
        <td><input id="product0_Discrepancy" name="product0_Discrepancy"/></td>
        <td><input id="product1_Discrepancy" name="product1_Discrepancy"/></td>
    </tr>

</table>

1 Ответ

1 голос
/ 14 января 2011

Проблема заключается в том, что расхождение является методом объекта Product, а не свойства. Нельзя связать элемент DOM с методом, только со свойством.

Способ, которым я решил проблему, состоит в том, чтобы (a) сделать Discrepancy свойством и (b) использовать методы convert и convertBack, чтобы убедиться, что это новое свойство было обновлено правильно.

Вот мой блок скриптов:

function Product() {
    this.InStock = 0;
    this.Ordered = 0;
    this.Discrepancy = 0;
}

var products = [];

$(document).ready(function () {

    products[0] = new Product();
    products[1] = new Product();

    var calcDiscrepancy = function(value, source, target) {
        $(target).data("Discrepancy", target.InStock - target.Ordered);
        return value;
    };

    var changeInStock = function (value, source, target) {
        target.InStock = value;
        return calcDiscrepancy(value, source, target)            ;
    };

    var changeOrdered = function (value, source, target) {
        target.Ordered = value;
        return calcDiscrepancy(value, source, target)            ;
    };

    var showDiscrepancy = function(value, source, target) {
        $(target).text(value.toString());
    };

    $("form").link(products[0], {
        InStock: {
            name: "product0_InStock",
            convert: changeInStock
        }, 
        Ordered: {
            name: "product0_Ordered",
            convert: changeOrdered
        },
        Discrepancy: {
            name: "product0_Discrepancy",
            convertBack: showDiscrepancy
        }
    });

    $("form").link(products[1], {
        InStock: {
            name: "product1_InStock",
            convert: changeInStock
        }, 
        Ordered: {
            name: "product1_Ordered",
            convert: changeOrdered
        },
        Discrepancy: {
            name: "product1_Discrepancy",
            convertBack: showDiscrepancy
        }
   });
});

Проходя через это:

  1. добавить свойство Discrepancy к классу Product со значением по умолчанию 0. Удалите материал ComputeDiscrepancy.

  2. напишите пару функций, которые принимают к сведению изменения в InStock и Ordered. Они обновят соответствующие свойства целевого объекта, а затем вызовут функцию с именем calcDiscrepancy и вернут ее возвращаемое значение.

  3. calcDiscrepancy обновит значение до свойства Discrepancy целевого объекта. Чтобы все события были вызваны этим изменением, я использовал метод jQuery .data().

  4. написать метод showDiscrepancy, который бы обновлял содержимое цели с использованием переданного значения (цель будет элементом DOM). Я также изменил элементы «несоответствия» вместо текстовых полей: иначе это не имело смысла.

  5. Вызовы link() теперь отображают соответствующие элементы DOM на соответствующие свойства и задают конвертеры для каждого. Для свойства InStock конвертер является типом convert и вызывает changeInStock и т. Д. Для свойства Discrepancy конвертер является типом convertBack, который вызывает showDiscrepancy. (По сути, convert переходит от элемента DOM к свойству объекта, а convertBack переходит от свойства к элементу.)

...