【问题标题】:Scope Problems in AngularJS with AngularJS Material使用 AngularJS 材料的 AngularJS 中的范围问题
【发布时间】:2017-06-21 17:46:06
【问题描述】:

我一直在尝试创建一个对话框,我可以在其中编辑一些信息。关键是您打开对话框,对话框中已经存在的内容,您可以对其进行编辑然后保存。我的问题是将信息从普通页面传递到对话框。这是控制器的代码:

export class MainController {
    constructor ($scope, $log, $document, $mdDialog, demosService) {
        'ngInject';

        $scope.addDemo = function (name, html) {
            demosService.addDemo(name, html);
        };

        $scope.removeDemo = function (name, html) {
            demosService.removeDemo(name, html);
        };

        $scope.updateDemo = function (oldName, newName, html) {

        };

        $scope.getDemoInfo = function (name) {

        };

        $scope.getDemos = function () {
            return demosService.getDemos();
        };

        $scope.hide = function () {
            $mdDialog.hide();
        };

        $scope.cancel = function () {
            $mdDialog.cancel();
        };

        $scope.saveNew = function () {
            $scope.addDemo($scope.newdemo.name, $scope.newdemo.html);
            $scope.cancel();
        };

        $scope.loggle = function (log) {
            $log.log(log);
        }

        $scope.saveEdit = function (oldname) {
            //$scope.updateDemo($scope.demo.name, $scope.demo.newname, $scope.demo.newhtml);
            console.log($scope.oldname + ", " + $scope.newname + ", " + $scope.newhtml);
        };

        $scope.showNewDemo = function (ev) {
            $mdDialog.show({
                controller: MainController,
                template: "<form ng-cloak style='width: 800px'><md-toolbar><div class='md-toolbar-tools'><h2 style='color: #fff !important;'>New Demo</h2><span flex></span><md-button class='md-icon-button' ng-click='cancel()'>"
                +         "<i class='material-icons' style='color: #fff !important;'>clear</i></md-button></div></md-toolbar><md-dialog-content>"
                + "<div class='md-dialog-content'><md-input-container class='md-block'><label>Name</label><input ng-model='newdemo.name'></md-input-container></div><md-input-container class='md-block' style='padding-left: 25px; padding-right: 25px;'><label style='margin-left:25px; margin-bottom: 5px;'>HTML</label><textarea ng-model='newdemo.html' rows='5' md-select-on-focus></textarea></md-input-container ></md-dialog-content><md-dialog-actions layout='row'>"
+                         "<span flex></span><md-button ng-click='cancel()'>Cancel</md-button><md-button ng-click='saveNew()'>Save</md-button></md-dialog-actions></form>",
                parent: angular.element($document.body),
                targetEvent: ev,
                clickOutsideToClose: true,
                fullscreen: $scope.customFullscreen
            });
        };

        $scope.newname = "foo";
        $scope.newhtml = "bar";

        $scope.showEditDemo = function () {
            console.log($scope.newname + ", " + $scope.newhtml + ", " + $scope.oldname);
            $mdDialog.show({
                controller: MainController,
                template: "<form ng-controller='MainController' ng-cloak style='width: 800px'><md-toolbar><div class='md-toolbar-tools'><h2 style='color: #fff !important;'>Edit Demo</h2><span flex></span><md-button class='md-icon-button' ng-click='cancel()'>"
                + "<i class='material-icons' style='color: #fff !important;'>clear</i></md-button></div></md-toolbar><md-dialog-content>"
                + "<div class='md-dialog-content'><md-input-container class='md-block'><label>Name</label><input ng-model='newname'></md-input-container></div><md-input-container class='md-block' style='padding-left: 25px; padding-right: 25px;'><label style='margin-left:25px; margin-bottom: 5px;'>HTML</label><textarea ng-model='newhtml' rows='5' md-select-on-focus></textarea></md-input-container></md-dialog-content><md-dialog-actions layout='row'>"
                + "<span flex></span><md-button ng-click='cancel()'>Cancel</md-button><md-button ng-click='loggle()'>Save</md-button></md-dialog-actions></form>",
                parent: angular.element($document.body),
                targetEvent: ev,
                clickOutsideToClose: true,
                fullscreen: $scope.customFullscreen
            });
        };
    }
}

现在,$scope.newname = "foo";$scope.newhtml = "bar"; 可以工作,但问题是我需要通过作用域函数来更改它们,即:

$scope.setVariables = function (name, html) {
    $scope.newname = name;
    $scope.newhtml = html;
}

如果您尝试在函数内console.log() 这些变量,它们会正常工作,但从对话框内部,它会恢复为函数外部描述的原始值。该功能是必需的,具有这些值的对话框也是必需的。提前谢谢大家!

【问题讨论】:

  • 嗨@WubbaLubbaDubbDubb,这是理解您问题的最短示例吗? stackoverflow.com/help/mcve
  • @KonstantinA.Magg 我相信是这样,但如果不是这样,请帮我解决这个问题,谢谢

标签: javascript angularjs angularjs-scope angular-material


【解决方案1】:

我有一个类似的场景,并通过让当前控制器兼作 mdDialog 的控制器来解决它。这是我使用的代码:

        var me = this
        this.$mdDialog.show({
            templateUrl: "components/listFilter/listFilterDialog.html",
            targetEvent: $event,
            parent: parentEl,
            controller: function () { return me },
            controllerAs: '$filterController',
            clickOutsideToClose: true,
            escapeToClose: true
        })

我没有使用 $scope,因为首先,这很糟糕。 :) 如果您使用 controllerAs 或更好的组件,您将获得更多的里程。

话虽如此,我想如果你使用类似的东西:

var thisScope = $scope
$mdDialog.show({
                controller: MainController,
                template: "...",
                locals: { data: thisScope}
                parent: angular.element($document.body),
                targetEvent: ev,
                clickOutsideToClose: true,
                fullscreen: $scope.customFullscreen
            });

我认为它会起作用或接近。这会将一个名为 data 的项目注入到对话框的控制器中。然后你会在你的模板中绑定它。

【讨论】:

  • 那么,如果我想访问该范围内的数据,我会说{{data.newname}} 而不是简单的{{newname}}?
  • 我不确定 mainController 是您当前的控制器还是新的控制器。假设它是一个新控制器,是的,但是您需要将 $scope.data = data 添加到控制器的构造函数代码中。
  • MainController 是我唯一的控制器。它用于对话框和普通 HTML 页面,以便它们可以更轻松地共享数据。您能否在答案中添加一个示例,其中包括 $scope.data = data 的东西?谢谢
  • 我认为,由于您正在尝试使控制器多用途(这可能是个坏主意),因此使用数据方法可能行不通。我建议制作一个只为对话框服务的控制器。然后在该控制器的构造函数中,您将通过注入获取数据并将其分配给 $scope.data (或您的控制器对象)。如果你想把它放在一个 plunker 里,我会看看我能不能帮你把它包起来。
  • 即使编译器不工作,我只提供plunker中的相关文件可以吗?如果是这样,这是链接:plnkr.co/edit/l84tOFWzFWBtYwJxXN1z
【解决方案2】:

您可以通过服务传输数据。

例如,假设您在父页面和子页面中都使用服务,比如说myService

然后你想将一些数据从父控制器传递给子控制器,那么你可以将父控制器中的值设置为服务如下:

myService.myObject=scope.myObject;

稍后您可以从服务访问子控制器中的相同对象,如下所示:

$scope.myObject=myService.myObject;

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 2015-10-14
    • 2019-07-16
    相关资源
    最近更新 更多