Контроллер виджетов Dojo - PullRequest
0 голосов
/ 23 мая 2011

Я работаю над новым проектом и пытаюсь заставить контроллер JS решить, какие виджеты dojo нужны для конкретной страницы.

У меня это работает, но только когда я вставляю / жестко кодирую JS виджета Dojo на страницу. Как только я пытаюсь заставить его работать с механизмами обеспечения и запроса dojo, все перестает работать, и я получаю следующую ошибку:

Could not load 'pf.PasswordStrength'; last tried '../dojopf/widget/PasswordStrength.js'
http://pf-dev-ad/wcsstore/js/dojo131/dojo/dojo.js
Line 16

Firebug показывает эту ошибку сразу после включения файла!

У меня есть реальные проблемы с этим, так как dojo 1.3.1 (который мне не разрешено обновлять) очень плохо документирован и не так много учебников.

Требование следующее:

  • 1 JS-контроллер всего сайта (lib.js)
  • 1 JS-файл для виджета (PasswordStrength.js)
  • 1 файл шаблона виджета (PasswordStrength.html)
  • 1 указатель узла

Структура файла настраивается следующим образом:

js
  dojo131
    dijit
    dojo
    dojotest
        widget
            templates
                PasswordStrength.html
                PasswordStrength.css
            PasswordStrength.js
    dojox

// JS-контроллер (lib.js):

if(!ad){ var ad = {} }

ad.base = new (function(){
    // init function will run on page load. Called by dojo.addOnLoad
    this.init = function (){
        /* This function acts as a controller for Dojo widgets.
        // it uses a variable ('pageName') set by the JSTL in the parent JSP of a particular page

        switch(ad.pageName){
            case 'Home':            
                _getTemplateAssets('PasswordStrength');
                break;
        }

    }

    var $ = dojo.query;
    var templatePath = 'js/dojo131/dojotest/widget';
    var debug = false; // This should be set to false when on production

    /*** PRIVATE FUNCTIONS ***/ 
    function _getTemplateAssets(templateName){
        // Injects the JS and CSS template assets into the page head

        dojo.registerModulePath("ad", '../dojotest/widget'); // relative to dojo.js
        //dojo.provide('ad.' + templateName);
        dojo.require('ad.' + templateName);

        //var headTag = document.getElementsByTagName('head').item(0);
        //dojo.create("script", { src: templatePath + '/' + templateName + '.js', type: 'text/javascript' }, headTag);
        //dojo.create("link", { href: templatePath + '/templates/' + templateName + '.css', type: 'text/css', rel: 'stylesheet' }, headTag);
    }


});

/*** ONLOAD ***/
dojo.addOnLoad(ad.base.init);

// Виджет JS (PasswordStrength.js)

if(!ad){ var ad = {} }

ad.passwordCheck = new (function(){
    // init function will run on page load. Called by dojo.addOnLoad
    this.init = function (){
        _temp_addPasswordCheck();
    }


    /*** PRIVATE VARIABLES ***/
    var $ = dojo.query;
    var templateName = 'PasswordStrength';
    var insertPointID = 'ins_passStrength';
    var minLength = 6;
    var objAdvice = { enterPass: 'Please enter a password', addChars: 'Add more characters (min ' + minLength + ')', addSpecials: 'Use special characters (!@#$%^&*)', addUppers: 'Use some upper case characters', addLowers: 'Use some lower case characters', addNums: 'Use some numbers', remRepeats: 'Too many repeated repeat characters', passPass: 'Your password has been verified as Excellent!' };
    var complexity = ['Bad', 'Very weak', 'Weak', 'Good', 'Strong', 'Excellent'];
    var content =   {
                        titles: {
                                    h1: 'Password Strength'
                                },
                        labels: {
                                    password: 'Password:',
                                    confirmPassword: 'Confirm Password',
                                    obscure: 'Obscure:',
                                    strength: 'Password strength:',
                                    advice: 'Advice:'
                                },
                        content:{
                                    advice: 'Please enter a password',
                                    strength: 'None'
                                }
                    }

    /*** PRIVATE FUNCTIONS ***/
    function _temp_addPasswordCheck(){
        // Include extras

        dojo.provide("ad.PasswordStrength");
        dojo.require("ad.PasswordStrength");
        dojo.require("dijit._Widget");
        dojo.require("dijit._Templated");
        dojo.require("dojo.parser");

        dojo.declare(templateName, [dijit._Widget, dijit._Templated], {

            // calls the HTML template to be used
            templatePath: dojo.moduleUrl ('dojotest.widget','templates/' + templateName + '.html'),
            // Content (titles, labels and general content)
            label_password: content.labels.password,
            label_confirmPassword: content.labels.confirmPassword,
            label_obscure: content.labels.obscure,
            label_passwordStrength: content.labels.strength,
            label_advice: content.labels.advice,
            title_passwordStrength: content.titles.h1,
            content_advice: content.content.advice,
            content_strength: content.content.strength,
            obscurePassword: function(){
                if(this.obscurePass.checked){  dojo.attr(this.passwordValue, 'type', 'password'); }
                else{ dojo.attr(this.passwordValue, 'type', 'text'); }
            },
            checkPassword: function(){
                            // This function checks the password strength on keyup and alters the passwordAdvice div to reflect the strength of the password entered

                            // Runs the password through a validation function which returns the results
                            var results = _checkPassWord(this.passwordValue.value), score = results['score'];
                            var ele = dojo.byId('passStrength');

                            // Update the markup to inform the user of their passwords score
                            if(results['count'] == 0){
                                this.complexity.innerHTML = 'None';
                                ele.className = '';
                                this.advice.innerHTML = _doInsert([objAdvice.enterPass]);
                            }
                            else if(score <= 50){
                                this.complexity.innerHTML = complexity[0];
                                ele.className = 'bad';
                                this.advice.innerHTML = _doInsert(results.advice);
                            }
                            if(score == 60){
                                this.complexity.innerHTML = complexity[1];
                                ele.className = 'veryWeak';
                                this.advice.innerHTML = _doInsert(results.advice);
                            }
                            if(score == 70){
                                this.complexity.innerHTML = complexity[2];
                                ele.className = 'weak';
                                this.advice.innerHTML = _doInsert(results.advice);
                            }
                            if(score == 80){
                                this.complexity.innerHTML = complexity[3];
                                ele.className = 'good';
                                this.advice.innerHTML = _doInsert(results.advice);
                            }
                            if(score == 90){
                                this.complexity.innerHTML = complexity[4];
                                ele.className = 'strong';
                                this.advice.innerHTML = _doInsert(results.advice);
                            }
                            if(score >= 100){
                                this.complexity.innerHTML = complexity[5];
                                ele.className = 'excellent';
                                this.advice.innerHTML = _doInsert([objAdvice.passPass]);
                            }
            }
        });
        // Calls the template into the right ID defined as the insert point as the first child
        if(dojo.byId(insertPointID)){
            var passStrength = new PasswordStrength().placeAt(insertPointID);
        }
    };

    function _doInsert(arrInsert){
        var content = '';
        dojo.forEach(arrInsert, function(item, i){
            content = content + '<p>' + item + '</p>';
        });
        return content; 
    }

    function _checkPassWord(strPassword){
        // Grades the password string and returns the results
        var objResults = {}, scoreFactor = 10, score = 0, advice = [], lengthPass, alphaLCpass, alphaUCpass, numPass, specialsPass, repeatPass, count = strPassword.length;

        // Check password string for uppercase alphas, lowercase alphas, numerals, special characters and repeated characters
        alphaUCpass = strPassword.match(/[A-Z]/g) ? true : false;
        alphaLCpass = strPassword.match(/[a-z]/g) ? true : false;
        numPass = strPassword.match(/[0-9]/g) ? true: false;
        specialsPass = strPassword.match(/[^a-zA-Z0-9]/g) ? true : false;
        repeatPass = strPassword.match(/(.)\1\1/g) ? false : true;
        lengthPass = count >= minLength ? true : false;

        // Score the password based on the results of the check
        if(alphaUCpass){ score += scoreFactor; }
        else{ advice.push(objAdvice.addUppers); }

        if(alphaLCpass){ score += scoreFactor; }
        else{ advice.push(objAdvice.addLowers); }

        if(numPass){ score += scoreFactor; }
        else{ advice.push(objAdvice.addNums); }

        if(specialsPass){ score += scoreFactor; }
        else{ advice.push(objAdvice.addSpecials); }

        if(repeatPass){ score += scoreFactor; }
        else{ advice.push(objAdvice.remRepeats); }

        if(lengthPass){ score += scoreFactor * 5; }
        else{ advice.push(objAdvice.addChars); }

        // Inserts the results into object to be returned
        objResults =    {
                            'alphaUC': alphaUCpass,
                            'alphaLC': alphaLCpass,
                            'numerals': numPass,
                            'specials': specialsPass,
                            'length': lengthPass,
                            'repeat': repeatPass,
                            'count': count,
                            'score': score,
                            'advice': advice
                        }

        // Return results to parent function
        return objResults;  
    }

    /*** PUBLIC FUNCTIONS ***/
});

/*** ONLOAD ***/
dojo.addOnLoad(ad.passwordCheck.init);

// HTML-шаблон виджета (PasswordStrength.html)

<div>
    <h1>${title_passwordStrength}</h1>
    <form method="post" action="">
        <fieldset>
            <div class="formFields">
                <label for="password">${label_password}</label>
                <input type="password" name="password" id="password" dojoAttachPoint="passwordValue" dojoAttachEvent="onkeyup: checkPassword" />
            </div>
            <div class="formFields">
                <label for="confirmPassword">${label_confirmPassword}</label>
                <input type="password" name="confirmPassword" id="confirmPassword" dojoAttachPoint="passwordConfirmValue" dojoAttachEvent="onkeyup: checkPassword" />
            </div>
            <div class="formFields">
                <label for="obscurePassword" class="wAuto">${label_obscure}</label>
                <input class="wAuto" type="checkbox" value="true" checked="checked" name="obscurePassword" id="obscurePassword" dojoAttachPoint="obscurePass"  dojoAttachEvent="onchange: obscurePassword" />
            </div>
            <div class="formFields">
                <label>${label_passwordStrength}</label>
                <div dojoAttachPoint="strength" id="passStrength" class=""></div>
                <div dojoAttachPoint="complexity" id="passStrengthCaption">${content_strength}</div>
            </div>
            <div class="formFields">
                <label>${label_advice}</label>
                <div dojoAttachPoint="advice" id="passAdvice"><p>${content_advice}</p></div>
            </div>
        </fieldset> 
    </form>

В родительском файле есть указатель HTML в следующем виде:

<div id="ins_passStrength" dojoType="PasswordStrength"></div>

Если я изменю следующую функцию в родительском контроллере (lib.js):

function _getTemplateAssets(templateName){
        // Injects the JS and CSS template assets into the page head

        dojo.registerModulePath("ad", '../dojotest/widget'); // relative to dojo.js
        //dojo.provide('ad.' + templateName);
        dojo.require('ad.' + templateName);

        //var headTag = document.getElementsByTagName('head').item(0);
        //dojo.create("script", { src: templatePath + '/' + templateName + '.js', type: 'text/javascript' }, headTag);
        //dojo.create("link", { href: templatePath + '/templates/' + templateName + '.css', type: 'text/css', rel: 'stylesheet' }, headTag);
    }

Кому:

function _getTemplateAssets(templateName){
        // Injects the JS and CSS template assets into the page head

        dojo.registerModulePath("ad", '../dojotest/widget'); // relative to dojo.js
        dojo.provide('ad.' + templateName);
        dojo.require('ad.' + templateName);

        //var headTag = document.getElementsByTagName('head').item(0);
        //dojo.create("script", { src: templatePath + '/' + templateName + '.js', type: 'text/javascript' }, headTag);
        //dojo.create("link", { href: templatePath + '/templates/' + templateName + '.css', type: 'text/css', rel: 'stylesheet' }, headTag);
    }

Ошибка исчезает, но расширенный JS не включен.

И если вы измените его на:

function _getTemplateAssets(templateName){
        // Injects the JS and CSS template assets into the page head

        dojo.registerModulePath("ad", '../dojotest/widget'); // relative to dojo.js
        //dojo.provide('ad.' + templateName);
        //dojo.require('ad.' + templateName);

        var headTag = document.getElementsByTagName('head').item(0);
        dojo.create("script", { src: templatePath + '/' + templateName + '.js', type: 'text/javascript' }, headTag);
        dojo.create("link", { href: templatePath + '/templates/' + templateName + '.css', type: 'text/css', rel: 'stylesheet' }, headTag);
    }

Работает нормально, но это грязный шаг ... Мне нужно использовать предписанные методы додзё.

Любая помощь с благодарностью.

Спасибо!

Ответы [ 2 ]

1 голос
/ 23 мая 2011

Я считаю, что ваша ошибка в том, что вы поместили свой dojo.provide("ad.PasswordStrength") в набор функций. Это должно быть в верхней части файла. Dojo оценивает файл, который он считает правильным (на основе пути к модулю), но как он должен знать, находится ли PasswordStrength там, если вы не скажете ему "да, этот файл предоставляет ad.PasswordStrength".

Редактировать: учитывая то, что вы сказали в IRC, вот как я думаю, PasswordStrength.js должен выглядеть так:

dojo.provide("ad.PasswordStrength");

if(!ad){ var ad = {} }

ad.passwordCheck = new (function(){

    // init function will run on page load. Called by dojo.addOnLoad
    this.init = function (){
        _temp_addPasswordCheck();
        dojo.parser.parse();
    }


    /*** PRIVATE VARIABLES ***/
    var $ = dojo.query;
    var templateName = 'PasswordStrength';
    ....

    /*** PRIVATE FUNCTIONS ***/
    function _temp_addPasswordCheck(){

        // Include extras
        dojo.require("dijit._Widget");
        dojo.require("dijit._Templated");
        dojo.require("dojo.parser");

        dojo.declare("ad." + templateName, [dijit._Widget, dijit._Templated], {

            // calls the HTML template to be used
            templatePath: dojo.moduleUrl ('dojotest.widget','templates/' + templateName + '.html'),
            // Content (titles, labels and general content)
            label_password: content.labels.password,
            label_confirmPassword: content.labels.confirmPassword,
            label_obscure: content.labels.obscure,
            label_passwordStrength: content.labels.strength,
            label_advice: content.labels.advice,
            title_passwordStrength: content.titles.h1,
            content_advice: content.content.advice,
            content_strength: content.content.strength,

            obscurePassword: function(){
                ....
            },
            checkPassword: function(){
                ....
            }
        });

        /*
        if(dojo.byId(insertPointID)){
            var passStrength = new PasswordStrength().placeAt(insertPointID);
        }
        */

    };

    function _doInsert(arrInsert){
        ....
    }

    function _checkPassWord(strPassword){
        ....
    }

    /*** PUBLIC FUNCTIONS ***/
});

/*** ONLOAD ***/
dojo.addOnLoad(ad.passwordCheck.init);
  • Перемещено dojo.provide("ad.PasswordStrength"); в начало файла.
  • Удалено dojo.require("ad.PasswordStrength"); из _temp_addPasswordCheck() - если этот код выполняется, ad.PasswordStrength (PasswordStrength.js), очевидно, уже требуется и загружен.
  • Добавлен dojo.parser.parse(); в конце init(), так что после объявления виджета любой виджет dojoTypes в HTML будет проанализирован. Тем не менее, я до сих пор не понимаю, почему вы должны объявить виджет внутри _temp_addPasswordCheck. Почему бы не включить виджет в файл и ad.passwordCheck, где бы ни находились другие "страничные" файлы ваших приложений?
  • Добавлено "объявление". к объявлению виджета (dojo.declare("ad." + templateName)), здесь должно быть полное имя в пространстве имен.
  • Закомментировано new PasswordStrength().placeAt(.... Поскольку вы хотите декларативно вставлять свои виджеты в HTML-код, нет смысла вручную создавать его здесь и размещать вручную.

Теперь вы сможете размещать виджеты PasswordStrength в своем HTML, например:

<script type="text/javascript" src="js/dojo131/dojo/dojo.js"></script>
<script type="text/javascript" src="js/dojo131/dojotest/lib.js"></script>
....
<div id="ins_passStrength" dojoType="ad.PasswordStrength"></div>
<div id="anotherOne" dojoType="ad.PasswordStrength"></div>

Помните, что здесь вам также нужно полное имя в пространстве имен (т. Е. Префикс объявления).

Это хорошо сработало для меня, используя Dojo 1.3.3. Загрузил песочницу, если она есть.

0 голосов
/ 23 мая 2011

Ваша ошибка:

Could not load 'pf.PasswordStrength'; last tried '../dojopf/widget/PasswordStrength.js'
http://pf-dev-ad/wcsstore/js/dojo131/dojo/dojo.js
Line 16

Это опечатка?Потому что он должен пытаться ../dojotest/widget/PasswordStrength.js

У вас есть еще один dojo.require, который относится к dojopf?Или любая другая строка, как dojo.require("pf.PasswordStrength")?

Если нет, возможно, регистрация пути к модулю не происходит до того, как dojo попытается загрузить ваши .js.Возможно, попробуйте использовать dojo.require для загрузки lib.js.

...