在 KnockoutJS 和 AngularJS 之间传递变量 [英] Passing variables between KnockoutJS and AngularJS

查看:23
本文介绍了在 KnockoutJS 和 AngularJS 之间传递变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  1. 我在创建 SPA 仪表板时使用了 Knockout.它运行良好.但是我们需要在仪表板中添加越来越复杂的东西,因此我们计划在 Angular 中开发仪表板的其余部分.

  2. 我的问题是如何将变量从淘汰赛传递给 Angular.我尝试使用 set 和 get 方法,但它没有帮助我..3.所以,我这样试过,我想在ko函数中设置一个属性值,就像这样..

  • <a href='javascript:;'数据绑定=点击:setMgmtEnv"><span>管理组织</span></a>
  • ///////在主JS文件中var x = document.getElementById("setMgmtEnv");x.setAttribute("value", "0");//////在 KO 模型中self.setMgmtEnv = function(){x.setAttribute("值", "1");}/////////在 Angular 中,我注意到这样的变化变量$scope.$watch(function(load) {返回 $scope.toLoad = document.getElementById('setMgmtEnv').value;},函数(新值,旧值){console.log("$scope.toLoad2 :" + $scope.toLoad);如果($scope.toLoad){console.log("$scope.toLoad3 :" + $scope.toLoad);$http({方法:'获取',网址:网址}).成功(功能(数据){控制台日志(数据);}).错误(函数(数据){alert("失败信息:" + JSON.stringify({数据:数据}));});}}

    解决方案

    在一个应用程序中混合使用 KnockoutJS 和 AngularJS 是一个很大的危险信号.请确保您了解自己在做什么,否则最好在 Angular 中重写 KO 部分.

    话虽如此,我可以尝试回答您提出的问题,尽管不是在您提供的代码片段的上下文中(非常不清楚).

    KO 可以通过三种主要方式与 Angular 交互(您似乎在问这个方向):

    1. 他们各自控制自己的 DOM 部分.KO 将通过 Javascript 代码通知"Angular.这将是首选情况.
    2. 他们各自控制自己的 DOM 部分.KO 将通过影响 Angular 实际控制的一块 DOM 来通知"Angular.
    3. 他们共享对同一 DOM 部分的控制权.KO 会自动通知" Angular,因为它会在变量更改时更新 DOM,而 Angular 的双向绑定会接收到这一点.

    选项 2 和 3 是灾难的秘诀.它们可以完成,但如果太糟糕了,我将创建一个 PoC 作为读者的练习.

    剩下的选项 1 在特定情况下实际上很有用.为此,您需要以下成分:

    • 在 Angular 的范围内引用 KO ViewModel;
    • 订阅 KO 的 ViewModel 相关部分;
    • 调用 $scope.$apply 不会通知 Angular KO 订阅回调已更改范围.

    这是一个例子:

    var ViewModel = function() {this.name = ko.observable("");};var vm = new ViewModel();angular.module("demoApp", []).controller("myCtrl", ["$scope", function($scope) {$scope.name = vm.name();vm.name.subscribe(function(newVal) {$scope.$apply(function() {$scope.name = newVal;});});}]);ko.applyBindings(vm, document.getElementById("knockoutArea"));

    div { margin: 5px;填充:5px;边框:1px 实心#edd;背景颜色:#fee;}

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script><div id="knockoutArea"><strong>击倒</strong><br>输入您的姓名:<input data-bind="textInput: name">

    <div id="angularArea" ng-app="demoApp" ng-controller="myCtrl"><strong>角度</strong><br>我们知道您的名字是:<strong>{{ name }}</strong>

    作为替代方案,鉴于 Angular 似乎是您前进的方向,您可能想要反转依赖关系.给 KO 一个对 Angular 的引用,并使你的代码调用的遗留"部分在 Angular 作用域上进行更新.这会让你的 KO 代码更脏,但会让你未来的代码库更干净.

    1. I am using Knockout in my SPA dashboard creation. Its working good.But we need to add more and more complex things in our dashboard, so we planned to develop the remaining part of dashboard in Angular.

    2. My question is how can i pass variables from knockout to Angular. I tried using set and get methods, but it didn't helped me.. 3.So, i tried like this, i would like to set an attribute value in the ko function when, like this..

    <li id="setMgmtEnv">
      <a href='javascript:;' data-bind="click: setMgmtEnv">
        <span>Manage Orgs</span>
      </a>
    </li>
    

    ///////in Main JS file
    var x = document.getElementById("setMgmtEnv"); 
            x.setAttribute("value", "0");
        ////// In KO model
        self.setMgmtEnv =  function(){
                    x.setAttribute("value", "1");           
                }
        ///////// In Angular i am noticing the change variable like this
       $scope.$watch(function(load) {
        return $scope.toLoad = document.getElementById('setMgmtEnv').value;
    }, function(newValue, oldValue) {
        console.log("$scope.toLoad2 : " + $scope.toLoad);
        if ($scope.toLoad) {
            console.log("$scope.toLoad3 : " + $scope.toLoad);
            $http({
                method : 'GET',
                url : url
            }).success(function(data) {
                console.log(data);
            }).error(function(data) {
                alert("Failure message: " + JSON.stringify({
                    data : data
                }));
            });
        }}
    

    解决方案

    Mixing KnockoutJS and AngularJS in one application is a big red flag. Be sure you understand what you're doing, or you'll probably be better off rewriting the KO parts in Angular.

    Having said that, I can try to answer the question you're asking, though not in the context of the code snippet you provided (which is very unclear).

    There are three main ways KO can interact with Angular (which is the direction you seem to be asking about):

    1. They each control their own piece of the DOM. KO will "notify" Angular through Javascript code. This would be the preferred situation.
    2. They each control their own piece of the DOM. KO will "notify" Angular by influencing a piece of the DOM actually controlled by Angular.
    3. They have shared control of the same piece of the DOM. KO "notifies" Angular automatically because it will update the DOM when a variable changes, and Angular's two-way bindings pick this up.

    Option 2 and 3 are a recipe for disaster. They can be done, but are that bad I'll leave creating a PoC as an excercise for the reader.

    That leaves option 1, which in specific cases can actually be useful. To do so you need these ingredients:

    • Within Angular's scope a reference to the KO ViewModel;
    • A subscription on the relevant part of KO's ViewModel;
    • A call to $scope.$apply no notify Angular the KO subscription callback has changed the scope.

    Here's an exmaple:

    var ViewModel = function() {
      this.name = ko.observable("");
    };
    
    var vm = new ViewModel();
    
    angular.module("demoApp", [])
      .controller("myCtrl", ["$scope", function($scope) {
        $scope.name = vm.name();
      
        vm.name.subscribe(function(newVal) {
          $scope.$apply(function() {
            $scope.name = newVal;
          });
        });
      }]);
    
    ko.applyBindings(vm, document.getElementById("knockoutArea"));

    div { margin: 5px; padding: 5px; border: 1px solid #edd; background-color: #fee; }

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    
    <div id="knockoutArea">
      <strong>Knockout</strong><br>
      Type your name: <input data-bind="textInput: name">
    </div>
    
    <div id="angularArea" ng-app="demoApp" ng-controller="myCtrl">
      <strong>Angular</strong><br>
      We know your name is: <strong>{{ name }}</strong>
    </div>

    As an alternative, given that Angular seems to be your way forward, you may want to invert the dependency. Give KO a reference to Angular and make that "legacy" part of your code call updates on the Angular scopes. This makes your KO code a lot dirtier, but keeps your future codebase cleaner.

    这篇关于在 KnockoutJS 和 AngularJS 之间传递变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    其他开发最新文章
    热门教程
    热门工具
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆