如何让 AngularJS 和 KendoUI 协调工作?

Posted

技术标签:

【中文标题】如何让 AngularJS 和 KendoUI 协调工作?【英文标题】:How to get AngularJS and KendoUI working in harmony? 【发布时间】:2014-02-20 11:46:09 【问题描述】:

我分阶段设置了我的 .Net MVC 解决方案,并确保 Angular JS 和 KendoUI 都能独立工作。

app.js:

var app = angular.module("app", ['kendo.directives']);

在我的控制器中,我定义了以下内容:

app.controller('contentTypesController', ['$scope', '$log', 'contentTypesRepository',
    function ($scope, $log, contentTypesRepository) 

        var a = ;

        $scope.status;
        $scope.contentTypes;

        $scope.contentTypeOptions;

        // for testing purposes, but not used - used for navigation properties
        $scope.users;

        getContentTypes();

        function getContentTypes() 
            // call the data repository
            contentTypesRepository.getList()
                .success(function (contentTypes) 
                    //console.log(contentTypes.value[0].Description);
                    //$log.log(contentTypes.value[0].Description)
                    $scope.contentTypes = contentTypes;
                    $scope.contentTypeOptions = 
                        dataSource: 
                            data: contentTypes
                        ,
                        dataTextField: "Description",
                        dataValueField: "ContentTypeId",
                        optionLabel: "Select a Content Type"
                    ;

                )
                .error(function (error) 
                    $scope.status = 'Unable to load data: ' + error.message;
                );
        

        $scope.updateContentTypes = function (id) 
            var contentType;

            for (var i = 0; i < $scope.contentTypes.length; i++) 
                var currentType = $scope.contentTypes[i];
                if (currentType.ID === id) 
                    contentType = currentType;
                    break;
                
            
        ;

        $scope.insertContentType = function () 
            // get contentType description from the client
            var contentType =  'Description': $scope.newContentType ;

            contentTypesRepository.insert(contentType)
                .success(function () 
                    $scope.status = 'Added new content type.  Refreshing list.';
                    // add the new content type to the client-side collection
                    $scope.contentTypes.value.push(
                                     'Description': $scope.newContentType 
                                );
                    $scope.newContentType = "";
                )
                .error(function (error) 
                    $scope.status = 'Unable to insert new content type: ' + error.message;
                );
        ;

        $scope.deleteContentType = function(id) 
            contentTypesRepository.remove(id)
                .success(function () 
                    $scope.status = 'Deleted content type.  Refreshing list.';
                    for (var i = 0; i < $scope.contentTypes.length; i++) 
                        var contentType = $scope.contentTypes[i];
                        if (contentType.ID === id) 
                            // remove the content type from the client-side collection
                            $scope.contentTypes.splice(i, 1);
                            break;
                        
                    
                    // navigation properties = null
                    // $scope.xxxx = null;
                )
                .error(function (error) 
                    $scope.status = 'Unable to delete content type: ' + error.message;
                );
        ;

        // get some navigation property
        //$scope.getCustomerOrders = function (id) 
        //    dataFactory.getOrders(id)
        //    .success(function (orders) 
        //        $scope.status = 'Retrieved orders!';
        //        $scope.orders = orders;
        //    )
        //    .error(function (error) 
        //        $scope.status = 'Error retrieving customers! ' + error.message;
        //    );
        //;


        $scope.addContentType = function () 

            //return $scope.newContentType.$save();
            $scope.contentTypes.value.push(
                 'Description': $scope.newContentType 
            );
            $scope.newContentType = "";
        

按照 Angluar/Kendo 示例 here,我添加了与 $scope.contentTypeOptions 相关的代码。

在我看来:

<select kendo-drop-down-list k-options="contentTypeOptions"></select>

显示下拉列表,但没有数据。

我可以查看ng-repeater 中的数据:

                        <ul>
                            <li ng-repeat="contentType in contentTypes.value">
                                 contentType.Description 
                            </li>
                        </ul>

以及 contentTypeOptions 的原始数据。

由于中继器使用 contentTypes.value,我也尝试过

                    $scope.contentTypeOptions = 
                        dataSource: 
                            data: contentTypes.value  // tried both contentTypes and contentTypes.value
                        ,
                        dataTextField: "Description",
                        dataValueField: "ContentTypeId",
                        optionLabel: "Select a Content Type"
                    ;

...基于 JSON 数据:

最终,我希望将所有 CRUD 连接到一个网格(我过去使用 OData 完成过,但现在将 AngularJS 添加到混合中)并认为只需在 Angular/Kendo 混合中显示数据即可是一个好的开始。我希望在解决这个问题后,剩下的会很简单,并感谢任何建议。

【问题讨论】:

我会在 github angular-kendo repo 中问这个问题,但即便如此,kendo ui 似乎也没有太多关注该项目。我已经设法用角度连接了一个相当不错的剑道网格和多选设置,但没有任何其他剑道小部件。 contentTypes.value的类型是什么? @LarsHöppner - value 是一个包含内容类型对象的集合/数组。 【参考方案1】:

您的代码有点混乱,因为像$scope.updateContentTypes 这样的方法将$scope.contentTypes 视为一个数组,但同时contentTypes 似乎是一个对象,其属性value 是一个数组。

需要注意的一点是,Kendo UI 小部件会在内部将您的数组转换为 Kendo 数据源。这意味着您对$scope.contentTypes 所做的更改不会影响$scope.contentTypeOptions 中数据源中的项目。

另一个问题是 angular-kendo 中的小部件和数据源之间没有完全的双向绑定,直到最近,除非您明确将其声明为 DataSource,否则数据源根本不会更新。据我所知,最近有一些改进,尽管它还没有完全集成。 (您可以尝试自己对数据进行深度观察,但这可能会产生性能问题;请参阅此处的related 帖子)。

您的下拉菜单未显示数据,因为您在创建小部件后替换了$scope.contentTypeOptions,并且该属性上没有$watch 可以使用这些选项更新小部件。 您可以显式创建一个 DataSource 并使用以下命令更新它:

$scope.contentTypeOptions.dataSource.data(contentType.value);

或者你可以使用属性:

k-data-source="contentTypes" 

这将在$scope.contentTypes 上创建一个$watch,因此当您替换它时,小部件也会更新。

也许这个基本的(虽然有点混乱)example 会对您有所帮助(我以与您相同的方式设置第二个下拉菜单;“更改”按钮更新数据源)。

【讨论】:

好的,所以我让你的例子工作了 - 谢谢。但是,我正在使用一个工厂来填充 getContentTypes() 中的数据(通过 OData 提供程序,这就是您在其中看到 .value 的原因)。当我尝试这样做时,在.success(function (contentTypes) 这不起作用。我在这里 jsbin.com/EdoyUxU/2/edit 创建了类似的东西,但我没有像上面的例子那样做。 只要你有一个包含所需元素的数组,你的数据来自哪里就不会产生影响;我需要查看一个无效的示例来进一步帮助您 我很惊讶没有对这个答案投票。这绝对有效,用于将剑道多选与异步资源数据绑定。 提供的示例不起作用。有更新的例子吗? @Bloodhound AngularJS 支持现在是 Kendo UI 的一部分,因此演示非常过时;你可以在这里找到 Kendo UI 和 AngularJS 的文档:docs.telerik.com/kendo-ui/AngularJS/the-grid-widget【参考方案2】:

您需要使用来自 Kendo 实验室的 Angular Kendo 绑定。

这是一篇带有现场演示和完整源代码的文章:

http://blog.longle.io/2014/05/01/angularjs-kendo-ui-using-angular-kendo-with-asp-net-mvc-5-web-api-odata

【讨论】:

以上是关于如何让 AngularJS 和 KendoUI 协调工作?的主要内容,如果未能解决你的问题,请参考以下文章

使用 AngularJS 服务代替 KendoUI 调度程序中的 url

kendoui + angularjs + 自动完成显示文本但将 id 设置为值

KendoUI AngularJS Bootstrap

KendoUI 表 + AngularJS

Kendo UI和AngularJS常见问题解析

KendoUI 下拉过滤器不适用于 AngularJS