2013-11-27 23 views
1

我一直在負責製作了一些在我們網站上的選項取決於已完成任務的先決條件。是否有一個簡單的Javascript庫或腳本來處理簡單的邏輯測試?

現在我存儲與字符串先決條件的對象。例如:

Task1 = {...}; 
Task2 = {preq:'Task1', ...} 

所以我可以很容易地檢查Task2是否僅在Task1完成時纔可用。

的問題是,這些任務變得更加複雜,我需要允許與/或邏輯。理想的情況是我能夠使用這樣的表達

Task4 = {prereq:'(Task1&Task2)|Task3}, ...} 

這將使task4可如果任一任務1和2已經完成或任務3已經完成。

我真的不知道即將去的最佳方式。我覺得也許我需要一個解析器或類似的東西,所以我會很感激解決方案或至少在正確方向上的指針。

編輯

現在,我使用一個類似的系統:http://jsfiddle.net/jEzaz/

我希望能夠潛在使用範圍AND和OR條件。現在,我只是被要求允許一個超過它是很容易(如完成任務1或任務2意味着你現在可以做TASK3) - 但是我可以看到在未來更多功能的需求。

我希望所有有道理!

+0

你可以使用評分系統......每個任務都有一個分數,你必須檢查最低分數值。 – rafaelcastrocouto

+1

你可以嘗試使用一些數據結構而不是字符串 – Grundy

+0

如何使用這個? – Grundy

回答

1

工作樣本可以實現一個簡單的解析器轉換字符串先決條件返回true/false的函數。檢查這個小提琴http://jsfiddle.net/tarabyte/a9F6Z/

var Task = (function() { 
    //string to function converter 
    var parse = function(str) { 
     str = "return " + str.replace(/\|/g, '||') 
       .replace(/&/g, '&&') 
       .replace(/(\w+\d+)/g, function($1) { 
        return 'all["' + $1 + '"].done'; 
       }); 
     return new Function("all", str);   
    }, 
     returnTrue = function() { 
      return true; 
     }, 
     all = {}; 
    /** 
    * Task constructor 
    */ 
    function Task(params) { 
     this.name = params.name; 
     //task is available by default 
     this.prereq = params.prereq ? parse(params.prereq) : returnTrue; 
     //task is not done. 
     this.done = false; 
     //register a task. 
     Task.all[this.name] = this; 
    }; 

    /** 
    * All tasks map storage. 
    */ 
    Task.all = all; 

    /** 
    * Make a task complete 
    */ 
    Task.prototype.complete = function() { 
     this.done = true; 
    }; 

    /** 
    * Make a task incomplete. 
    */ 
    Task.prototype.reopen = function() { 
     this.done = false; 
    }; 

    /** 
    * Check if task is available due to prerequsites. 
    */ 
    Task.prototype.isAvailable = function() { 
     return this.prereq(all); 
    }; 

    return Task; 
}()); 
+0

非常感謝!在某些方面看起來很簡單。 –

2

的樣品,你可以嘗試使用一個結構和功能檢查

如果任何先決條件將被設置爲null
如果一個 - 將設置字符串名稱如果幾個有或
- 將使用對象{or: ["task1","task2"...]}
如果幾個與和 - 將使用對象{and: ["task1","task2"...]}

也結合 - 將使用對象像{and: [{or:["task1","task2"]},"task3",{or:{"task5"...}}]}

所以樣本的任務列表可能是這樣

var myObj = { 
    task1: {name: 'Hello', prereq:null, selected: false}, 
    task2: {name: 'World', prereq:'task1', selected: false}, 
    task3: {name: 'Foo', prereq:{or:["task4","task2"]}, selected: false}, 
    task4: {name: 'Bar', prereq:null, selected: false}, 
    task5: {name: 'Baz', prereq:{and:[{or: ["task4","task6"]},"task1"]}, selected: false}, 
    task6: {name: 'Barrr', prereq:null, selected: false} 
}; 

檢查使用功能類似

function preq(arr,config){ 
    if(!config) return true; 
    if(typeof config === "string") return arr[config].selected; 
    if('or' in config){ 
     for(var i=0,L=config['or'].length;i<L;i++){ 
      if(preq(arr,config['or'][i])) return true; 
     } 
     return false; 
    } 
    if('and' in config){ 
     for(var i=0,L=config['and'].length;i<L;i++){ 
      if(!preq(arr,config['and'][i])) return false; 
     } 
     return true; 
    } 
    return false; 
} 

你也可以檢查JSFiiddle

+0

它的工作原理非常好 - 但Yury的簡單解析器解決方案似乎在這種情況下更容易實現。 –

+0

@JohnReid是的,你是對的:-) – Grundy