【问题标题】:Ember loading template multiple times and errorEmber 多次加载模板并报错
【发布时间】:2014-05-30 16:13:11
【问题描述】:

我遇到了一个问题,Ember (1.6.0-beta.4) 似乎正在尝试第二次加载相同的视图,而不是转换到不同的视图。

应用程序有一个登录视图,然后是主页视图。登录视图加载得很好。那里没有问题。用户输入他们的信用并点击登录。当成功响应返回时,应用程序将转换到主页(路由会按应有的方式更新)。

但不是渲染主页面,而是渲染登录页面和主页面堆叠在一起。在控制台中,出现错误:“Uncaught Error: Assertion Failed: Attempted to register a view with an id already in use: userName”

唯一具有 id 为“userName”的元素的视图是登录视图,这让我相信它正在尝试第二次呈现登录页面(这不是我想要的)。

Ember 检查器不会显示任何不合适的地方。当我刷新主页时,错误消失了。

这是我的应用程序的相关部分(从一系列 js 文件中复制和粘贴,我尽量让事情井井有条)

我的模板:

<script type="text/x-handlebars">
    {{#if loggedIn}}
        <nav>
            <img id="navLogo" src="images/ExsellsiorMAnagerLogo.png" />
            <!--<div class="pull-right">Hello {{FirstName}}!</div>-->
        </nav>
        {{outlet}}
    {{else}}
        {{outlet}}
    {{/if}}
</script>
<script type="text/x-handlebars" id="manifests">
    <div class="container-fluid">
        <div class="row">
            {{render 'filter' model}}
            <div id="library" class="col-md-3 left-column"><h2>Library</h2></div>
            <div id="stage" class="col-md-7 bg-danger"><h2>Stage</h2></div>
        </div>
    </div>
</script>
<script type="text/x-handlebars" id="login">
    <div class="container">
        <form id="login-form" role="form" class="form-horizontal" {{action login on="submit"}}>
            <div class="form-group">
                <img src="images/ExsellsiorMAnagerLogo.png" alt="Exsellsior Manager Logo" />
            </div>
            <div class="form-group">
                <label for="userName" class="control-label hidden">User Name</label>
                {{input id="userName" type="text" class="form-control" placeholder="User Name" value=userName }}
            </div>
            <div class="form-group">
                <label for="pwd" class="control-label hidden">Password</label>
                {{input id="pwd" type="password" class="form-control" placeholder="Password" value=password}}
            </div>
            <div class="form-group">
                {{#if inProcess}}
                    <button id="loginBtn" class="btn btn-primary has-spinner spinner-active" type="submit">
                         Login<span class="spinner"><i class="icon-primary-spinner"></i></span>
                    </button>
                {{else}}
                     <button id="loginBtn" class="btn btn-primary has-spinner" type="submit">
                          Login<span class="spinner"><i class="icon-primary-spinner"></i></span>
                     </button>
                {{/if}}
            </div>
            {{#if invalidLogin}}
                 <div id="failure-message" class="form-group has-error bg-danger">
                     <span class="text-danger">Invalid username or password</span>
                 </div>
            {{/if}}
         </form>
    </div>
</script>

控制器:

app.ApplicationController = Em.Controller.extend({
    needs: ['login'],
    loggedIn: false,
    tokenChanged: function() {
        var self = this,
            login = self.get('controllers.login');

        if (login.get('token')) {
            this.set('loggedIn', true)
        } else {
            this.set('loggedIn', false)
        }
    },
    userInfoChanged: function () {
        var self = this,
            login = self.get('controllers.login');

        if (login.get('userInfo')) {
            this.setProperties(login.get('userInfo'));
        }
    },
    setState: function () {
        var self = this;
        var login = self.get('controllers.login');

        login.addObserver('token', self, self.tokenChanged);
        login.addObserver('userInfo', self, self.userInfoChanged);

        if (login.get('token')) {
            this.set('loggedIn', true);
            this.setProperties(login.get('userInfo'));
            this.transitionToRoute('manifests');
        } else {
            this.set('loggedIn', false);
            this.transitionToRoute('login');
        }
    }
});

app.LoginController = Em.Controller.extend({

    // resets login info so previous info is not stored
    reset: function () {
        var self = this;

        self.setProperties({
            userName: "",
            password: "",
            invalidLogin: false
        });
    },

    // define dependency on application controller
    //needs: ['application'],

    // initializes with user token, if one exists
    token: localStorage.getItem("token"),

    userInfo: JSON.parse(localStorage.getItem("userInfo")),

    // monitors if token changes and updates local storage if so
    tokenChanged: function() {
        localStorage.setItem("token", this.get('token'));
    }.observes('token'),

    userInfoChanged: function () {
        localStorage.setItem("userInfo", JSON.stringify(this.get('userInfo')))
    }.observes('userInfo'),

    actions: {
        // action to fire when user attempts to log in
        login: function () {
            var self = this;

            if (self.get('inProcess')) {
                return;
            }

            self.set('inProcess', true);

            // function.bind() specifies the context the function will be executed in
            //   (the 'this' object within the function)
            // login returns the promise from an AJAX call
            return app.util.login(self.get('userName'), self.get('password'))
                .then(loginSuccess.bind(self), loginFailure.bind(self));
        }
    }
});

app.FilterController = Em.ObjectController.extend({
    showing: true,
    actions: {
        collapse: function () {
            this.set('showing', !this.get('showing'));
        }
    }
});

路线:

app.Router.map(function () {
    // /login
    this.resource('login');

    // /manifests
    this.resource('manifests',function(){
        this.resource('filter');
    });
});

app.AuthenticatedRoute = Em.Route.extend({

    // checks if we have a token - if not we can assume we're
    //   not logged in before we make an ajax call
    beforeModel: function(transition) {
        if (!this.controllerFor('login').get('token')) {
            this.redirectToLogin(transition);
        }
    },

    // function to handle re-routing to login screen
    redirectToLogin: function(transition) {
        var loginController = this.controllerFor('login');
        loginController.set('attemptedTransition', transition);
        this.transitionTo('login');
    },

    // reusable function for data requests
    executeAjax: function(method, url, data) {
        var token = this.controllerFor('login').get('token');

        return app.util.executeAjax(method, url, token, data);
    },

    actions: {
        error: function(reason, transition) {
            if (reason.status === 401) {
                this.redirectToLogin(transition);
            } else {
                // todo: handle this better
                alert('Something went wrong');
            }
        }
    }
});

app.LoginRoute = Em.Route.extend({
    // ensures user data is cleared when login page loads/reloads
    setupController: function(controller, context) {
        controller.reset();
    }
});

app.ManifestsRoute = app.AuthenticatedRoute.extend({
    model: function () {
        return this.executeAjax("GET", "states").then(function (result) {
            return {
                states: result
            }
        });
    }
});

【问题讨论】:

    标签: javascript ember.js


    【解决方案1】:

    评论不能用在这样的车把里,

    <!--<div class="pull-right">Hello {{FirstName}}!</div>-->
    

    它们应该被包裹在车把里:

    {{!-- foo --}}
    

    你的出口也应该超出 if 语句的范围:

    {{#if loggedIn}}
        <nav>
            <img id="navLogo" src="images/ExsellsiorMAnagerLogo.png" />
            {{!-- <div class="pull-right">Hello {{FirstName}}!</div> --}}
        </nav>
    {{/if}}
    
    {{outlet}}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      相关资源
      最近更新 更多