telerik / kendo-ui-core

An HTML5, jQuery-based widget library for building modern web apps.
http://www.telerik.com/kendo-ui
Other
2.54k stars 1.91k forks source link

Pass the reference element in the arguments for the dependent methods in MVVM #7773

Open kendo-bot opened 6 months ago

kendo-bot commented 6 months ago

Currently, there is no way to reuse a single method of a model and execute different logic based on additional data related to the specific element.

Before the CSP improvements in R1 2023, an unsupported workaround was configuring the method along with the arguments that were evaluated and accessible from the method itself.

Example of the unsupported approach:

Improvement suggestion

Allow the model methods to have access to the reference element. That would enable the internal method logic to get additional data based on the element and achieve the same functionality as the unsupported workaround approach.

Example of the desired functionality:

    <div id="test">
      <p data-bind="text: spanLabel" data-span-label="test"></p>
      <p data-bind="text: spanLabel" data-span-label="another test"></p>
    </div>

    <script>
      var viewModel = kendo.observable({
        spanLabel: function(args) {
          let element = args.referenceElement; 
          let spanLabelArgs = element.attr("data-span-label")
          return "spanLabel executed, args: " + spanLabelArgs
        },
      });

      kendo.bind($("#test"), viewModel);
    </script>
failwyn commented 1 month ago

This can be fixed with a small CSP compliant code change to the get method in kendo.data.js. The fix restores full functionality for dependent methods that take parameters; applications require no code changes, it works exactly as it did before the breaking changes were introduced.

'          get: function(field) {
           var that = this, result;

           that.trigger(GET, { field: field });

           if (field === "this") {
               result = that;
           } else {
               // FIX: if the field is a function, extract arguments and remove parentheses
               var args = field.match(/\((.*)\)/)?.pop().split(',') || []
               field = field.replace(/ *\([^)]*\) */g, "");

               result = kendo.getter(field, true)(that);
               // FIX: if the result is a function, call it
               if (typeof result === 'function') {
                   var path = field.substring(0, field.lastIndexOf('.')),
                       source = path ? that.get(path) : that;

                   result = result.call(source, ...args);
               }
           }

           return result;
       },
 `
 // ignore the backticks around the code, github shouldn't be printing them